/* This doesn't look like -*- C -*-, but it is!
 *
 * arm.def - ARM ISA machine definition
 *
 * This file is a part of the SimpleScalar tool suite written by
 * Todd M. Austin as a part of the Multiscalar Research Project.
 *  
 * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
 * 
 * Copyright (C) 1997, 1998 by Todd M. Austin
 *
 * This source file is distributed "as is" in the hope that it will be
 * useful.  The tool set comes with no warranty, and no author or
 * distributor accepts any responsibility for the consequences of its
 * use. 
 * 
 * Everyone is granted permission to copy, modify and redistribute
 * this tool set under the following conditions:
 * 
 *    This source code is distributed for non-commercial use only. 
 *    Please contact the maintainer for restrictions applying to 
 *    commercial use.
 *
 *    Permission is granted to anyone to make or distribute copies
 *    of this source code, either as received or modified, in any
 *    medium, provided that all copyright notices, permission and
 *    nonwarranty notices are preserved, and that the distributor
 *    grants the recipient permission for further redistribution as
 *    permitted by this document.
 *
 *    Permission is granted to distribute this file in compiled
 *    or executable form under the same conditions that apply for
 *    source code, provided that either:
 *
 *    A. it is accompanied by the corresponding machine-readable
 *       source code,
 *    B. it is accompanied by a written offer, with no time limit,
 *       to give anyone a machine-readable copy of the corresponding
 *       source code in return for reimbursement of the cost of
 *       distribution.  This written offer must permit verbatim
 *       duplication by anyone, or
 *    C. it is distributed by someone who received only the
 *       executable form, and is accompanied by a copy of the
 *       written offer of source code that they received concurrently.
 *
 * In other words, you are welcome to use, share and improve this
 * source file.  You are forbidden to forbid anyone else to use, share
 * and improve what you give them.
 *
 * INTERNET: dburger@cs.wisc.edu
 * US Mail:  1210 W. Dayton Street, Madison, WI 53706
 *
 * $Id: arm.def,v 1.1.1.1 2000/11/29 14:53:54 cu-cs Exp $
 * Revision 1.1.2.23  2000/08/25 18:40:13  taustin
 * Started implementing funky PC semantics for ARM.
 *
 * Revision 1.1.2.22  2000/08/23 22:06:53  chriswea
 * now supports all long multiples.. changed the decode order it now
 * sees them right after ALUREG0 branch
 *
 * Revision 1.1.2.21  2000/08/23 20:33:04  chriswea
 * fixed the umull bug (added a link from the add to umulladd)
 *
 * Revision 1.1.2.20  2000/08/23 15:24:56  chriswea
 * Fixed the carry out flag for arm
 *
 * Revision 1.1.2.19  2000/08/22 18:38:52  taustin
 * More progress on the SimpleScalar/ARM target.
 *
 * Revision 1.1.2.18  2000/07/28 21:37:22  taustin
 * More debugging of the SimpleScalar/ARM target.
 *
 * Revision 1.1.2.17  2000/07/28 20:32:04  omutlu
 * *** empty log message ***
 *
 * Revision 1.1.2.16  2000/07/28 04:53:43  omutlu
 * fixed the post indexed ldr/strs
 *
 * Revision 1.1.2.15  2000/07/27 21:56:11  omutlu
 * corrections to shifts
 *
 * Revision 1.1.2.14  2000/07/27 21:45:04  taustin
 * Added umpteen half word and signed byte loads.
 *
 * Revision 1.1.2.13  2000/07/27 20:15:32  omutlu
 * fixes to ldr and str
 *
 * Revision 1.1.2.12  2000/07/27 19:41:42  omutlu
 * fixed bugs in tst,teq,cmn
 *
 * Revision 1.1.2.10  2000/07/27 17:51:26  omutlu
 * fixed monadic CPDO instructions
 *
 * Revision 1.1.2.9  2000/07/26 12:21:55  taustin
 * Fixed CPRT_LINK in ARM decode table.
 *
 * Revision 1.1.2.8  2000/07/26 06:32:18  omutlu
 *
 * More fixes to floating-point instructions
 *
 * Revision 1.1.2.7  2000/07/26 05:01:50  taustin
 * More disassembler fixes...
 *
 * Revision 1.1.2.6  2000/07/25 18:29:03  omutlu
 * Modified the branch offset calculation, cmp, ldm
 *
 * Revision 1.1.2.5  2000/07/21 18:30:59  taustin
 * More progress on the SimpleScalar/ARM target.
 *
 * Revision 1.1.2.4  2000/07/13 03:09:55  taustin
 * More progress on the SimpleScalar/ARM target.
 *
 * Revision 1.1.2.3  2000/07/01 13:35:37  taustin
 * More progress on the ARM target support...
 *
 * Revision 1.1.2.2  2000/06/01 19:35:18  taustin
 * ARM definition file, work in progress...
 *
 * Revision 1.1.2.1  2000/05/31 19:25:59  taustin
 * ARM definition files
 *
 * Revision 1.1.1.1  2000/05/26 15:22:27  taustin
 * SimpleScalar Tool Set
 *
 *
 * Revision 1.5  1999/12/31 18:56:17  taustin
 * quad_t naming conflicts removed
 * Alpha instruction set extensions (MVI, BWX, AMASK, IMPLVER, etc...)
 * 21-bit conditional branch offset fix
 *
 * Revision 1.4  1999/12/13 18:59:20  taustin
 * debug printf's removed
 *
 * Revision 1.3  1999/03/08 06:39:41  taustin
 * added Alpha BWX ISA extensions (byte and word loads)
 *
 * Revision 1.2  1998/08/31 17:14:07  taustin
 * fixed MS VC++ shift-by-64bit problems in EXT* instructions
 * fixed MS VC++ qword to double problem in FPCR instruction
 *
 * Revision 1.1  1998/08/27 16:53:47  taustin
 * Initial revision
 *
 *
 */

/* FIXME: these comments are out-of-date */

/* This file defines all aspects of the SimpleScalar instruction set
 * architecture.  Each instruction set in the architecture has a DEFINST()
 * macro call included below.  The contents of a instruction definition are
 * as follows:
 *
 *   DEFINST(<enum>,			<opcode>,
 *	     <opname>,			<operands>,
 *	     <fu_req>,			<iflags>,
 *	     <output deps...>,		<input deps...>,
 *	     <expr>)
 *
 * Where:
 *
 *   <enum>	- is an enumerator that is returned when an instruction is
 *		  decoded by SS_OP_ENUM()
 *   <opcode>	- is the opcode of this instruction
 *   <opname>   - name of this instruction as a string, used by disassembler
 *   <operands>	- specified the instruction operand fields and their printed
 * 		  order for disassembly, used by disassembler, the recognized
 *		  operand field are (the instruction format is detailed in
 *		  the header file ss.h):
 *		    J - target field
 *		    j - PC relative target (offset + PC)
 *		    s - S register field
 *		    b - S register field (base register)
 *		    t - T register field
 *		    d - D register field
 *		    S - S register field (FP register)
 *		    T - T register field (FP register)
 *		    D - D register field (FP register)
 *		    o - load address offset (offset)
 *		    i - signed immediate field value
 *		    u - unsigned immediate field value
 *		    U - upper immediate field value
 *		    H - shift amount immediate field value
 *		    B - break code
 *
 *   <fu_req>	- functional unit requirements for this instruction
 *   <iflags>	- instruction flags, accessible via the SS_OP_FLAGS()
 *		  macro, flags are defined with F_* prefix in ss.h
 *   <output deps...>
 *		- a list of up to two output dependency designators, the
 *		  following designators are recognized (place an DNA in any
 *		  unused fields:
 *		    DGPR(N)   - general purpose register N
 *		    DGPR_D(N) - double word general purpose register N
 *		    DCGPR(N)  - general purpose register conditional on
 *			        pre/post- increment/decrement mode
 *		    DFPR_L(N) - floating-point register N, as word
 *		    DFPR_F(N) - floating-point reg N, as single-prec float
 *		    DFPR_D(N) - floating-point reg N, as double-prec double
 *		    DHI	      - HI result register
 *		    DLO	      - LO result register
 *		    DFCC      - floating point condition codes
 *		    DCPC      - current PC
 *		    DNPC      - next PC
 *		    DNA	      - no dependence
 *
 *   <input deps...>
 *		- a list of up to three input dependency designators, the
 *		  designators are defined above (place an DNA in any unused
 *		  fields.
 *
 *   <expr>	- a C expression that implements the instruction being
 * 		  defined, the expression must modify all architected state
 *		  affected by the instruction's execution, by default, the
 *		  next PC (NPC) value defaults to the current PC (CPC) plus
 *		  SS_INST_SIZE, as a result, only taken branches need to set
 *		  NPC
 *
 *		  The following predefined macros are available for use in
 *		  DEFINST() instruction expressions to access the value of
 *		  instruction operand/opcode field values:
 *
 *		    RS	    - RS register field value
 *		    RT	    - RT register field value
 *		    RD	    - RD register field value
 *		    FS	    - RS register field value
 *		    FT	    - RT register field value
 *		    FD	    - RD register field value
 *		    BS	    - RS register field value
 *		    TARG    - jump target field value
 *		    OFS	    - signed offset field value
 *		    IMM	    - signed offset field value
 *		    UIMM    - unsigned offset field value
 *		    SHAMT   - shift amount field value
 *		    BCODE   - break code field value
 *
 *		  To facilitate the construction of performance simulators
 *		  (which may want to specialize their architected state
 *		  storage format), all architected register and memory state
 *		  is accessed through the following macros:
 *
 *		    GPR(N)         - read general purpose register N
 *		    SET_GPR(N,E)   - write general purpose register N with E
 *		    GPR_D(N)       - read double word general purpose reg N
 *		    SET_GPR_D(N,E) - write double word gen purpose reg N w/ E
 *		    FPR_L(N)       - read floating-point register N, as word
 *		    SET_FPR_L(N,E) - floating-point reg N, as word, with E
 *		    FPR_F(N)       - read FP reg N, as single-prec float
 *		    SET_FPR_F(N,E) - write FP reg N, as single-prec float w/ E
 *		    FPR_D(N)       - read FP reg N, as double-prec double
 *		    SET_FPR_D(N,E) - write FP reg N, as double-prec double w/E
 *		    HI	           - read HI result register
 *		    SET_HI(E)      - write HI result register with E
 *		    LO	           - read LO result register
 *		    SET_LO(E)      - write LO result register with E
 *		    FCC	           - read floating point condition codes
 *		    SET_FCC(E)     - write floating point condition codes w/ E
 *		    CPC	           - read current PC register
 *		    NPC	           - read next PC register
 *		    SET_NPC(E)     - write next PC register with E
 *		    TPC	           - read target PC register
 *		    SET_TPC(E)     - write target PC register with E
 *
 *		    READ_SIGNED_BYTE(A)   - read signed byte from address A
 *		    READ_UNSIGNED_BYTE(A) - read unsigned byte from address A
 *		    READ_SIGNED_HALF(A)   - read signed half from address A
 *		    READ_UNSIGNED_HALF(A) - read unsigned half from address A
 *		    READ_WORD(A)          - read word from address A
 *		    WRITE_BYTE(E,A)       - write byte value E to address A
 *		    WRITE_HALF(E,A)       - write half value E to address A
 *		    WRITE_WORD(E,A)       - write word value E to address A
 *
 *		  Finally, the following helper functions are available to
 *		  assist in the construction of instruction expressions:
 *
 *		    INC_DEC(E,N,S) - execute E and update N as per pre/post-
 *				     incr/decr addressing sementics for an
 *				     access of S bytes
 *		    OVER(X,Y)      - check for overflow for X+Y, both signed
 *		    UNDER(X,Y)	   - check for umderflow for X-Y, both signed
 *		    DIV0(N)	   - check for divide by zero, N is denom
 *		    INTALIGN(N)    - check double word int reg N alignment
 *		    FPALIGN(N)	   - check double word FP reg N alignment
 *		    TALIGN(T)	   - check jump target T alignment
 */

#if 0
/* TOP LEVEL decode table */
DEFLINK(TOPLEV, 0x00, "toplev", 24, 0x0f)
CONNECT(TOPLEV)
#endif

/* most simulators ignore the UOP definitions */
#ifndef DEFUOP
#define DEFUOP(OP,NAME,OPFORM,RES,FLAGS,O1,O2,O3,I1,I2,I3,I4)
#endif /* !DEFUOP */
     
/* funky PC semantics macros */
#define GPR_SH(N)	(((N) != 15) ? GPR(N) : (GPR(15)+(SHIFT_REG ? 12 : 8)))
#define GPR_EX(N)	(((N) != 15) ? GPR(N) : (GPR(15)+8))
#define GPR_MEM(N)	(((N) != 15) ? GPR(N) : (GPR(15)+12))
#define GPR_BASE(N)	(((N) != 15)					\
			 ? (((N) == (RN) && !_first) ? _wbaddr : GPR(N))\
			 : (GPR(15)+12))
#define GPR_RES(N)	(((N) == (RD)) ? _result : GPR(N))

/* dependence helper macros */
#define DCOND		(((COND) == COND_AL) ? DNA : DPSR)
#define DCONDSH		(((COND) == COND_AL)				\
			 ? (((SHIFT_BITS) == 0) ? DNA : DPSR)		\
			 : DPSR)
#define DSHRS(RS)	(((SHIFT_BITS) == 0) ? DNA : DGPR(RS))


DEFLINK(ALUREG0_LINK, 0x00, "alureg0_link", 4, 0x0f)

DEFLINK(ALUREG1_LINK, 0x01, "alureg1_link", 4, 0x0f)

DEFLINK(ALUIMM0_LINK, 0x02, "aluimm0_link", 20, 0x0f)

DEFLINK(ALUIMM1_LINK, 0x03, "aluimm1_link", 20, 0x0f)

DEFLINK(MEMIMMPOST_LINK, 0x04, "memimmpost_link", 20, 0x0f)

DEFLINK(MEMIMMPRE_LINK, 0x05, "memimmpre_link", 20, 0x0f)

DEFLINK(MEMREGPOST_LINK, 0x06, "memregpost_link", 20, 0x0f)

DEFLINK(MEMREGPRE_LINK, 0x07, "memregpre_link", 20, 0x0f)

DEFLINK(BLKPOST_LINK, 0x08, "blkpost_link", 20, 0x0f)

DEFLINK(BLKPRE_LINK, 0x09, "blkpre_link", 20, 0x0f)

#define BR_IMPL								\
  {									\
    SET_TPC(CPC + BOFS + 8);						\
									\
    if (COND_VALID(PSR))						\
      {									\
	SET_NPC(CPC + BOFS + 8);					\
      }									\
  }
DEFINST(BR,			0x0a,
	"b%c",			"%j",
	IntALU,			F_CTRL|F_DIRJMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define BRL_IMPL							\
  {									\
    SET_TPC(CPC + BOFS + 8);						\
									\
    if (COND_VALID(PSR))						\
      {									\
	SET_NPC(CPC + BOFS  + 8);					\
	SET_GPR(14, CPC + 4);						\
      }									\
  }
DEFINST(BRL,			0x0b,
	"bl%c",			"%j",
	IntALU,			F_CTRL|F_DIRJMP,
	DGPR(14), DNA, DNA,	DCOND, DNA, DNA, DNA)

DEFLINK(CDXPOST_LINK, 0x0c, "cdxpost_link", 8, 0x0f)

DEFLINK(CDXPRE_LINK, 0x0d, "cdxpre_link", 8, 0x0f)

DEFLINK(CPROC_LINK, 0x0e, "cproc_link", 8, 0x0f)

#define SWI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SYSCALL(inst);							\
      }									\
  }
DEFINST(SWI,			0x0f,
	"swi%c",		"%S",
	NA,			F_TRAP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(ALUREG0_LINK)

DEFLINK(ALUREG0a_LINK, 0x0f00, "alureg0a_link", 20, 0x0f)

/* FIXME: 0x00 is SWP */
DEFLINK(MUL_LINK, 0x09, "mul_link", 20, 0x0f)

DEFLINK(LDRHSTRH_LINK, 0x0b, "ldrhstrh_link", 20, 0x0f)

DEFLINK(LDRSBSTRSB_LINK, 0x0d, "ldrsbstrsb_link", 20, 0x0f)

DEFLINK(LDRSHSTRSH_LINK, 0x0f, "ldrshstrsh_link", 20, 0x0f)


CONNECT(ALUREG1_LINK)

DEFLINK(ALUREG1a_LINK, 0x0f00, "alureg1a_link", 20, 0x0f)

/* FIXME: 0x00 is SWP */


DEFLINK(LDRH_PSTRH_P_LINK, 0x0b, "ldrh_pstrh_p_link", 20, 0x0f)

DEFLINK(LDRSB_PSTRSB_P_LINK, 0x0d, "ldrsb_pstrsb_p_link", 20, 0x0f)

DEFLINK(LDRSH_PSTRSH_P_LINK, 0x0f, "ldrsh_pstrsh_p_link", 20, 0x0f)


CONNECT(ALUREG0a_LINK)

#define AND_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_SH(RN) & SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));	\
      }									\
  }
DEFINST(AND,			0x00,
	"and%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define ANDS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	_result = GPR_SH(RN) & SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);	\
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ANDS,			0x01,
	"and%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define EOR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_SH(RN) ^ SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));	\
      }									\
  }
DEFINST(EOR,			0x02,
	"eor%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define EORS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	_result = GPR_SH(RN) ^ SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);	\
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(EORS,			0x03,
	"eor%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define SUB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(RD, GPR_SH(RN) - SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));	\
      }									\
  }
DEFINST(SUB,			0x04,
	"sub%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define SUBS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
        word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
        word_t _result = _lhs - _rhs;					\
									\
        SET_PSR_N((sword_t)_result < 0);				\
        SET_PSR_Z(_result == 0);					\
        SET_PSR_C(SUBC(_lhs, _rhs, _result));				\
        SET_PSR_V(SUBV(_lhs, _rhs, _result));				\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(SUBS,			0x05,
	"sub%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define RSB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(RD, SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C) - GPR_SH(RN));	\
      }									\
  }
DEFINST(RSB,			0x06,
	"rsb%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define RSBS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
        word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
        word_t _result = _rhs - _lhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_rhs, _lhs, _result));				\
	SET_PSR_V(SUBV(_rhs, _lhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(RSBS,			0x07,
	"rsb%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define ADD_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(RD, GPR_SH(RN) + SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));	\
      }									\
  }
DEFINST(ADD,			0x08,
	"add%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define ADDS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
	word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
	word_t _result = _lhs + _rhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(ADDC(_lhs, _rhs, _result));				\
	SET_PSR_V(ADDV(_lhs, _rhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ADDS,			0x09,
	"adds%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define ADC_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(RD, GPR_SH(RN) + SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C) + PSR_C);\
      }									\
  }
DEFINST(ADC,			0x0a,
	"adc%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define ADCS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
	word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
	word_t _result = _lhs + _rhs + PSR_C;				\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(ADDC(_lhs, _rhs, _result));				\
	SET_PSR_V(ADDV(_lhs, _rhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ADCS,			0x0b,
	"adc%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define SBC_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(RD, GPR_SH(RN) - SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C)-!PSR_C);\
      }									\
  }
DEFINST(SBC,			0x0c,
	"sbc%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define SBCS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
	word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
	word_t _result = _lhs - _rhs - !PSR_C;				\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_lhs, _rhs, _result));				\
	SET_PSR_V(SUBV(_lhs, _rhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(SBCS,			0x0d,
	"sbc%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define RSC_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(RD, SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C) - GPR_SH(RN)-!PSR_C);\
      }									\
  }
DEFINST(RSC,			0x0e,
	"rsc%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define RSCS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
	word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
	word_t _result = _rhs - _lhs - !PSR_C;				\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_rhs, _lhs, _result));				\
	SET_PSR_V(SUBV(_rhs, _lhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(RSCS,			0x0f,
	"rsc%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))


CONNECT(ALUREG1a_LINK)

DEFLINK(SWPMRS_LINK, 0x00, "swpmrs_link", 4, 0xff)

#define TSTS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result = GPR_SH(RN) & SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);\
						                        \
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
      }									\
  }
DEFINST(TSTS,			0x01,
	"tst%cs",		"%n,%m",
	IntALU,			F_ICOMP,
	DPSR, DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

DEFLINK(MSRTEQ_LINK, 0x02, "msrteq_link", 12, 0x7f)

#define TEQS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result = GPR_SH(RN) ^ SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);\
									\
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
      }									\
  }
DEFINST(TEQS,			0x03,
	"teq%cs",		"%n,%m",
	IntALU,			F_ICOMP,
	DPSR, DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

DEFLINK(MRSSWP_LINK, 0x04, "mrsswp_link", 4, 0xff)

#define CMPS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
	word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
	word_t _result = _lhs - _rhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_lhs, _rhs, _result));				\
	SET_PSR_V(SUBV(_lhs, _rhs, _result));				\
      }									\
  }
DEFINST(CMPS,			0x05,
	"cmp%c",		"%n,%m",
	IntALU,			F_ICOMP,
	DPSR, DPSR, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

DEFLINK(MSRTST_LINK, 0x06, "msrtst_link", 12, 0x7f)

#define CMNS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: should this be GPR_SH? following the ARMulator */	\
	word_t _lhs = GPR_EX(RN);					\
	word_t _rhs = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);		\
	word_t _result = _lhs + _rhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(ADDC(_lhs, _rhs, _result));				\
	SET_PSR_V(ADDV(_lhs, _rhs, _result));				\
      }									\
  }
DEFINST(CMNS,			0x07,
	"cmn%c",		"%n,%m",
	IntALU,			F_ICOMP,
	DPSR, DPSR, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define ORR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_SH(RN) | SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));	\
      }									\
  }
DEFINST(ORR,			0x08,
	"orr%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define ORRS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	_result = GPR_SH(RN) | SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);	\
									\
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ORRS,			0x09,
	"orr%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define MOV_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));		\
      }									\
  }
DEFINST(MOV,			0x0a,
	"mov%c",		"%d,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RM), DSHRS(RS), DNA)

#define MOVS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	_result = SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);			\
									\
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(MOVS,			0x0b,
	"mov%cs",		"%d,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RM), DSHRS(RS), DNA)

#define BIC_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_SH(RN) & ~SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));	\
      }									\
  }
DEFINST(BIC,			0x0c,
	"bic%c",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RN), DGPR(RM), DSHRS(RS))

#define BICS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	_result = GPR_SH(RN) & ~SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);	\
									\
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(BICS,			0x0d,
	"bic%cs",		"%d,%n,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DGPR(RM), DSHRS(RS))

#define MVN_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, ~SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C));		\
      }									\
  }
DEFINST(MVN,			0x0e,
	"mvn%c",		"%d,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCONDSH, DGPR(RM), DSHRS(RS), DNA)

#define MVNS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	_result = ~SHIFTRM(GPR_SH(RM), GPR(RS), PSR_C);			\
									\
	SET_PSR_C(SHIFTC(GPR_SH(RM), GPR(RS), PSR_C));			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(MVNS,			0x0f,
	"mvn%cs",		"%d,%m",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RM), DSHRS(RS), DNA)


CONNECT(SWPMRS_LINK)

#if 0
DEFLINK(MRSTST_LINK, 0xff00, "mrstst_link", 0, 0xf0fff)

CONNECT(MRSTST_LINK)

#define MRS_CPSR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(MSR_CPSR,		EQ, 0xf0000,
	"msr",			"%d, cpsr",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DPSR, DNA, DNA)
#endif

#define TST_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* test but don't set flags, nada... */				\
      }									\
  }
DEFINST(TST,			0xff00,
	"tst%c",		"%n,%m",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define SWP_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(SWP,			0x09,
	"swp%c",		"%d,%w,%s,%n",
	IntMULT,		F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(MSRTEQ_LINK)

#define TEQ_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* test but don't set flags, nada... */				\
      }									\
  }
DEFINST(TEQ,			0x7f00,
	"teq%c",		"%n,%m",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define MSR_CPSR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(MSR_CPSR,		0x0f,
	"msr",			"cpsr,%d",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(MRSSWP_LINK)

#if 0
DEFLINK(MRSCMP_LINK, NE, 0x09, "mrscmp_link", 0, 0xf0fff)

CONNECT(MRSCMP_LINK)

#define MRS_SPSR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(MSR_SPSR,		EQ, 0xf0000,
	"mrs",			"%d, spsr",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DPSR, DNA, DNA, DNA)
#endif

#define CMP_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* compare but don't set flags, nada... */			\
      }									\
  }
DEFINST(CMP,			0xff00,
	"cmp%c",		"%n,%m",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define SWP1_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(SWP1,			0x09,
	"swp%c",		"%d,%w,%s,%n",
	IntMULT,		F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(MSRTST_LINK)

#define TST1_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* test but don't set flags, nada... */				\
      }									\
  }
DEFINST(TST1,			0x7f00,
	"tst%c",		"%n,%m",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define MSR_SPSR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(MSR_SPSR,		0x0f,
	"msr",			"spsr,%d",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(ALUIMM0_LINK)

#define ANDI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) & ROTR(ROTIMM,  ROTAMT << 1));		\
      }									\
  }
DEFINST(ANDI,			0x00,
	"and%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define ANDSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
        word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
									\
	_result = GPR_EX(RN) & ROTR(ROTIMM,  ROTAMT << 1);		\
        if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);                                  \
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ANDSI,			0x01,
	"and%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define EORI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) ^ ROTR(ROTIMM,  ROTAMT << 1));		\
      }									\
  }
DEFINST(EORI,			0x02,
	"eor%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define EORSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
        word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
									\
	_result = GPR_EX(RN) ^ ROTR(ROTIMM,  ROTAMT << 1);		\
        if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);                                  \
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(EORSI,			0x03,
	"eor%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define SUBI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) - ROTR(ROTIMM,  ROTAMT << 1));		\
      }									\
  }
DEFINST(SUBI,			0x04,
	"sub%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define SUBSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
        word_t _result = _lhs - _rhs;					\
									\
        SET_PSR_N((sword_t)_result < 0);				\
        SET_PSR_Z(_result == 0);					\
        SET_PSR_C(SUBC(_lhs, _rhs, _result));				\
        SET_PSR_V(SUBV(_lhs, _rhs, _result));				\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(SUBSI,			0x05,
	"sub%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define RSBI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, ROTR(ROTIMM,  ROTAMT << 1) - GPR_EX(RN));		\
      }									\
  }
DEFINST(RSBI,			0x06,
	"rsb%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define RSBSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
        word_t _result = _rhs - _lhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_rhs, _lhs, _result));				\
	SET_PSR_V(SUBV(_rhs, _lhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(RSBSI,			0x07,
	"rsb%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define ADDI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) + ROTR(ROTIMM,  ROTAMT << 1));		\
      }									\
  }
DEFINST(ADDI,			0x08,
	"add%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define ADDSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
	word_t _result = _lhs + _rhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(ADDC(_lhs, _rhs, _result));				\
	SET_PSR_V(ADDV(_lhs, _rhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ADDSI,			0x09,
	"add%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define ADCI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) + ROTR(ROTIMM,  ROTAMT << 1) + PSR_C);	\
      }									\
  }
DEFINST(ADCI,			0x0a,
	"adc%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DPSR, DGPR(RN), DNA, DNA)

#define ADCSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
	word_t _result = _lhs + _rhs + PSR_C;				\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(ADDC(_lhs, _rhs, _result));				\
	SET_PSR_V(ADDV(_lhs, _rhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ADCSI,			0x0b,
	"adc%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DNA, DNA)

#define SBCI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) - ROTR(ROTIMM,  ROTAMT << 1) - !PSR_C);	\
      }									\
  }
DEFINST(SBCI,			0x0c,
	"sbc%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DPSR, DGPR(RN), DNA, DNA)

#define SBCSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
	word_t _result = _lhs - _rhs - !PSR_C;				\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_lhs, _rhs, _result));				\
	SET_PSR_V(SUBV(_lhs, _rhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(SBCSI,			0x0d,
	"sbc%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DNA, DNA)

#define RSCI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, ROTR(ROTIMM,  ROTAMT << 1) - GPR_EX(RN) - !PSR_C);	\
      }									\
  }
DEFINST(RSCI,			0x0e,
	"rsc%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DPSR, DGPR(RN), DNA, DNA)

#define RSCSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
	word_t _result = _rhs - _lhs - !PSR_C;				\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_rhs, _lhs, _result));				\
	SET_PSR_V(SUBV(_rhs, _lhs, _result));				\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(RSCSI,			0x0f,
	"rsc%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DPSR, DGPR(RN), DNA, DNA)


CONNECT(ALUIMM1_LINK)

#define TSTI_IMPL							\
  {                                                                     \
    if (COND_VALID(PSR))						\
      {									\
	/* test but don't set flags, nada... */				\
      }									\
  }
DEFINST(TSTI,			0x00,
	"tst%c",		"%n,#%i",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define TSTSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
	word_t _result = GPR_EX(RN) & _imm;                    		\
									\
        if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);                                  \
  	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z((sword_t)_result == 0);				\
      }									\
  }
DEFINST(TSTSI,			0x01,
	"tst%cs",		"%n,#%i",
	IntALU,			F_ICOMP,
	DPSR, DNA, DNA,		DCOND, DGPR(RN), DNA, DNA)

DEFLINK(MSRITEQI_LINK, 0x02, "msriteqi_link", 12, 0x7f)

#define TEQSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {	                                                                \
	word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
        word_t _result = GPR_EX(RN) ^ ROTR(ROTIMM,  ROTAMT << 1);	\
                                                                        \
	if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);            			\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
      }									\
  }
DEFINST(TEQSI,			0x03,
	"teq%cs",		"%n,#%i",
	IntALU,			F_ICOMP,
	DPSR, DNA, DNA,		DCOND, DGPR(RN), DNA, DNA)

#define CMPI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* compare but don't set flags, nada... */			\
      }									\
  }
DEFINST(CMPI,			0x04,
	"cmp%c",		"%n,#%i", 
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define CMPSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
	word_t _result = _lhs - _rhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(SUBC(_lhs, _rhs, _result));				\
	SET_PSR_V(SUBV(_lhs, _rhs, _result));				\
      }									\
  }
DEFINST(CMPSI,			0x05,
	"cmp%c",		"%n,#%i",
	IntALU,			F_ICOMP,
	DPSR, DNA, DNA,		DCOND, DGPR(RN), DNA, DNA)

DEFLINK(MSRITSTI_LINK, 0x06, "msritsti_link", 12, 0x7f)

#define CMNSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _lhs = GPR_EX(RN), _rhs = ROTR(ROTIMM,  ROTAMT << 1);	\
	word_t _result = _lhs + _rhs;					\
									\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
	SET_PSR_C(ADDC(_lhs, _rhs, _result));				\
	SET_PSR_V(ADDV(_lhs, _rhs, _result));				\
      }									\
  }
DEFINST(CMNSI,			0x07,
	"cmn%c",		"%n,#%i",
	IntALU,			F_ICOMP,
	DPSR, DNA, DNA,		DCOND, DGPR(RN), DNA, DNA)

#define ORRI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) | ROTR(ROTIMM,  ROTAMT << 1));		\
      }									\
  }
DEFINST(ORRI,			0x08,
	"orr%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define ORRSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
								        \
	_result = GPR_EX(RN) | ROTR(ROTIMM,  ROTAMT << 1);		\
        if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);                                  \
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(ORRSI,			0x09,
	"orr%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define MOVI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, ROTR(ROTIMM,  ROTAMT << 1));			\
      }									\
  }
DEFINST(MOVI,			0x0a,
	"mov%c",		"%d,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DNA, DNA, DNA)

#define MOVSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
        word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
									\
	_result = ROTR(ROTIMM,  ROTAMT << 1);				\
        if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);                                  \
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(MOVSI,			0x0b,
	"mov%cs",		"%d,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DNA, DNA, DNA)

#define BICI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, GPR_EX(RN) & ~ROTR(ROTIMM,  ROTAMT << 1));		\
      }									\
  }
DEFINST(BICI,			0x0c,
	"bic%c",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define BICSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
        word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
									\
	_result = GPR_EX(RN) & ~ROTR(ROTIMM,  ROTAMT << 1);		\
        if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);                                  \
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(BICSI,			0x0d,
	"bic%cs",		"%d,%n,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DGPR(RN), DNA, DNA)

#define MVNI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, ~ROTR(ROTIMM,  ROTAMT << 1));			\
      }									\
  }
DEFINST(MVNI,			0x0e,
	"mvn%c",		"%d,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DNA, DNA, DNA)

#define MVNSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
        word_t _imm = ROTR(ROTIMM,  ROTAMT << 1);                       \
									\
	_result = ~ROTR(ROTIMM,  ROTAMT << 1);				\
        if (ROTAMT != 0)                                                \
          SET_PSR_C((_imm >> 31) & 1);                                  \
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(MVNSI,			0x0f,
	"mvn%cs",		"%d,#%i",
	IntALU,			F_ICOMP,
	DGPR(RD), DPSR, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(MSRITEQI_LINK)

#define TEQI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* test but don't set flags, nada... */				\
      }									\
  }
DEFINST(TEQI,			0x7f00,
	"teq%c",		"%n,#%i",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define MRSI_CPSR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(MRSI_CPSR,		0x0f,
	"mrs",			"cpsr,%d",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(MSRITSTI_LINK)

#define TSTI1_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* test but don't set flags, nada... */				\
      }									\
  }
DEFINST(TSTI1,			0x7f00,
	"tst%c",		"%n,#%i",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define MRSI_SPSR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(MRSI_SPSR,		0x0f,
	"mrs",			"spsr,%d",
	IntALU,			F_ICOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


     /* ALL OF THE MULL INSTRUCTIONS */
CONNECT(MUL_LINK)

#define MUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	if ((RM) == (RN))						\
	  {								\
	    SET_GPR(RN, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RN) == MD_REG_PC)						\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        SET_GPR(RN, GPR(RM) * GPR(RS));					\
      }									\
  }
DEFINST(MUL,			0x00,
	"mul%c",		"%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RN), DNA, DNA,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define MULS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	if ((RM) == (RN))						\
	  {								\
	    SET_PSR_N(0);						\
	    SET_PSR_Z(1);						\
	    SET_GPR(RN, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RN) == MD_REG_PC)						\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = GPR(RM) * GPR(RS);					\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RN, _result);						\
      }									\
  }
DEFINST(MULS,			0x01,
	"mul%cs",		"%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RN), DPSR,	DNA,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define MLA_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	if ((RM) == (RN))						\
	  {								\
	    SET_GPR(RN, GPR(RD));					\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RN) == MD_REG_PC)						\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        SET_GPR(RN, GPR(RM) * GPR(RS) + GPR(RD));			\
      }									\
  }
DEFINST(MLA,			0x02,
	"mla%c",		"%n,%w,%s,%d",
	IntMULT,		F_ICOMP,
	DGPR(RN), DNA, DNA,	DCOND, DGPR(RM), DGPR(RS), DGPR(RD))

#define MLAS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
									\
	if ((RM) == (RN))						\
	  {								\
	    SET_PSR_N((sword_t)GPR(RD) < 0);				\
	    SET_PSR_Z(GPR(RD) == 0);					\
	    SET_GPR(RN, GPR(RD));					\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RN) == MD_REG_PC)						\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = GPR(RM) * GPR(RS) + GPR(RD);				\
	SET_PSR_N((sword_t)_result < 0);				\
	SET_PSR_Z(_result == 0);					\
        SET_GPR(RN, _result);						\
      }									\
  }
DEFINST(MLAS,			0x03,
	"mla%cs",		"%n,%w,%s,%d",
	IntMULT,		F_ICOMP,
	DGPR(RN), DPSR, DNA,	DCOND, DGPR(RM), DGPR(RS), DGPR(RD))

#define UMULL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        qword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((qword_t)(word_t)GPR(RM))*((qword_t)(word_t)GPR(RS));\
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(UMULL,			0x08,
	"umull%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DNA,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define UMULLS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        qword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((qword_t)(word_t)GPR(RM))*((qword_t)(word_t)GPR(RS));\
	SET_PSR_N((sword_t)(!!_result) < 0);				\
	SET_PSR_Z((!!_result) == 0);					\
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(UMULLS,			0x09,
	"umulls%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DPSR,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define UMLAL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        qword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((qword_t)(word_t)GPR(RM))*((qword_t)(word_t)GPR(RS));\
        _result = _result + ((qword_t)(GPR(RN)) << 32) + ((qword_t)(word_t)GPR(RD));         \
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(UMLAL,			0x0a,
	"umlal%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DNA,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define UMLALS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        qword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((qword_t)(word_t)GPR(RM))*((qword_t)(word_t)GPR(RS));\
        _result = _result + (((qword_t)(word_t)(GPR(RN))<<32)) + ((qword_t)(word_t)GPR(RD));         \
	SET_PSR_N((sword_t)(!!_result) < 0);				\
	SET_PSR_Z((!!_result) == 0);					\
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(UMLALS,			0x0b,
	"umlals%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DPSR,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define SMULL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        sqword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((sqword_t)(sword_t)GPR(RM))*((sqword_t)(sword_t)GPR(RS));\
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(SMULL,			0x0c,
	"smull%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DNA,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define SMULLS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        sqword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((sqword_t)(sword_t)GPR(RM))*((sqword_t)(sword_t)GPR(RS));                  \
	SET_PSR_N((sword_t)(!!_result) < 0);				\
	SET_PSR_Z((!!_result) == 0);					\
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(SMULLS,			0x0d,
	"smulls%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DPSR,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define SMLAL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        sqword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((sqword_t)(word_t)GPR(RM))*((sqword_t)(word_t)GPR(RS));\
        _result = _result + ((sqword_t)(GPR(RN)) << 32) + ((sqword_t)(word_t)GPR(RD));         \
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(SMLAL,			0x0e,
	"smlal%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DNA,	DCOND, DGPR(RM), DGPR(RS), DNA)

#define SMLALS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        sqword_t _result;                                                \
                                                                        \
    if ((RM) == (RD) || (RM) == (RN) || (RN) == (RD))		        \
	  {								\
	    SET_GPR(RD, 0);						\
	    /* FIXME: should this be "md_fault_dsteqop1"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
	if ((RD) == MD_REG_PC || (RN) == MD_REG_PC)			\
	  {								\
	    /* FIXME: should this be "md_fault_pcdst"? */		\
	    DECLARE_FAULT(md_fault_invalid);				\
	  }								\
									\
        _result = ((sqword_t)(word_t)GPR(RM))*((sqword_t)(word_t)GPR(RS));\
        _result = _result + (((sqword_t)(word_t)(GPR(RN))<<32)) + ((sqword_t)(word_t)GPR(RD));         \
	SET_PSR_N((sword_t)(!!_result) < 0);				\
	SET_PSR_Z((!!_result) == 0);					\
        SET_GPR(RN, (word_t)(_result >> 32));				\
        SET_GPR(RD, (word_t)_result);    				\
      }									\
  }
DEFINST(SMLALS,			0x0f,
	"smlals%c",		"%d,%n,%w,%s",
	IntMULT,		F_ICOMP,
	DGPR(RD),DGPR(RN),DPSR,	DCOND, DGPR(RM), DGPR(RS), DNA)


CONNECT(LDRHSTRH_LINK)

#define STRH_R_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_HALF((half_t)GPR_MEM(RD), GPR_EX(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - GPR(RM);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_R,			0x00,
	"str%ch",		"%d,[%n],-%w",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DGPR(RM))

#define LDRH_RL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = (word_t)READ_HALF(GPR_EX(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - GPR_RES(RM);				\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDRH_RL,		0x01,
	"ldr%ch",		"%d,[%n],-%w",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x02: STRH_RW is invalid, W is implied... */

/* FIXME: 0x03: LDRH_RWL is invalid, W is implied... */

#define STRH_O_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_HALF((half_t)GPR_MEM(RD), GPR_SH(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
        _addr = GPR_EX(RN) - HOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_O,			0x04,
	"str%ch",		"%d,[%n],-#%h",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDRH_OL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - HOFS;					\
									\
	SET_GPR(RN, _addr); 					        \
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_OL,		0x05,
	"ldr%ch",		"%d,[%n],-#%h",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x06: STRH_OW is invalid, W is implied... */

/* FIXME: 0x07: LDRH_OWL is invalid, W is implied... */

#define STRH_RU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_HALF((half_t)GPR_MEM(RD), GPR_EX(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + GPR(RM);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_RU,		0x08,
	"str%ch",		"%d,[%n],%w",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DGPR(RM))

#define LDRH_RUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = (word_t)READ_HALF(GPR_EX(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + GPR_RES(RM);				\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDRH_RUL,		0x09,
	"ldr%ch",		"%d,[%n],%w",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x0a: STRH_RUW is invalid, W is implied... */

/* FIXME: 0x0b: LDRH_RUWL is invalid, W is implied... */

#define STRH_OU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_HALF((half_t)GPR_MEM(RD), GPR_EX(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
        _addr = GPR_EX(RN) + HOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_OU,		0x0c,
	"str%ch",		"%d,[%n],#%h",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDRH_OUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
        _addr = GPR_EX(RN) + HOFS;					\
        							        \
	SET_GPR(RN, _addr); 					        \
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_OUL,		0x0d,
	"ldr%ch",		"%d,[%n],#%h",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x0e: STRH_OUW is invalid, W is implied... */

/* FIXME: 0x0f: LDRH_OUWL is invalid, W is implied... */


CONNECT(LDRSBSTRSB_LINK)

/* FIXME: 0x00: STRSB_R is invalid... */

#define LDRSB_RL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = (word_t)(sword_t)(sbyte_t)READ_BYTE(GPR_EX(RN), _fault);\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - GPR_RES(RM);				\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDRSB_RL,		0x01,
	"ldr%csb",		"%d,[%n],-%w",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x02: STRSB_RW is invalid, W is implied... */

/* FIXME: 0x03: LDRSB_RWL is invalid, W is implied... */

/* FIXME: 0x04: STRSB_O is invalid... */

#define LDRSB_OL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - HOFS;					\
									\
	SET_GPR(RN, _addr); 				                \
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_OL,		0x05,
	"ldr%csb",		"%d,[%n],-#%h",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x06: STRSB_OW is invalid, W is implied... */

/* FIXME: 0x07: LDRSB_OWL is invalid, W is implied... */

/* FIXME: 0x08: STRSB_RU is invalid... */

#define LDRSB_RUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = (word_t)(sword_t)(sbyte_t)READ_BYTE(GPR_EX(RN), _fault);\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + GPR_RES(RM);				\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDRSB_RUL,		0x09,
	"ldr%csb",		"%d,[%n],%w",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x0a: STRSB_RUW is invalid, W is implied... */

/* FIXME: 0x0b: LDRSB_RUWL is invalid, W is implied... */

/* FIXME: 0x0c: STRSB_OU is invalid... */

#define LDRSB_OUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + HOFS;					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_OUL,		0x0d,
	"ldr%csb",		"%d,[%n],#%h",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x0e: STRSB_OUW is invalid, W is implied... */

/* FIXME: 0x0f: LDRSB_OUWL is invalid, W is implied... */


CONNECT(LDRSHSTRSH_LINK)

/* FIXME: 0x00: STRSH_R is invalid... */

#define LDRSH_RL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = (word_t)(sword_t)(shalf_t)READ_HALF(GPR_EX(RN), _fault);\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - GPR_RES(RM);				\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDRSH_RL,		0x01,
	"ldr%csh",		"%d,[%n],-%w",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x02: STRSH_RW is invalid, W is implied... */

/* FIXME: 0x03: LDRSH_RWL is invalid, W is implied... */

/* FIXME: 0x04: STRSH_O is invalid... */

#define LDRSH_OL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
        _addr = GPR_EX(RN) - HOFS;					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_OL,		0x05,
	"ldr%csh",		"%d,[%n],-#%h",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x06: STRSH_OW is invalid, W is implied... */

/* FIXME: 0x07: LDRSH_OWL is invalid, W is implied... */

/* FIXME: 0x08: STRSH_RU is invalid... */

#define LDRSH_RUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = (word_t)(sword_t)(shalf_t)READ_HALF(GPR_EX(RN), _fault);\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + GPR_RES(RM);				\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDRSH_RUL,		0x09,
	"ldr%csh",		"%d,[%n],%w",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x0a: STRSH_RUW is invalid, W is implied... */

/* FIXME: 0x0b: LDRSH_RUWL is invalid, W is implied... */

/* FIXME: 0x0c: STRSH_OU is invalid... */

#define LDRSH_OUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
        _addr = GPR_EX(RN) + HOFS;					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_OUL,		0x0d,
	"ldr%csh",		"%d,[%n],#%h",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x0e: STRSH_OUW is invalid, W is implied... */

/* FIXME: 0x0f: LDRSH_OUWL is invalid, W is implied... */


CONNECT(LDRH_PSTRH_P_LINK)

#define STRH_PR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
                                                                        \
	_addr = GPR_EX(RN) - GPR(RM);					\
	WRITE_HALF((half_t)GPR_MEM(RD), _addr, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STRH_PR,		0x00,
	"str%ch",		"%d,[%n,%w]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DGPR(RM))

#define LDRH_PRL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) - GPR(RM), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_PRL,		0x01,
	"ldr%ch",		"%d,[%n,%w]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

#define STRH_PRW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - GPR(RM);					\
	WRITE_HALF((half_t)GPR_MEM(RD), _addr, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_PRW,		0x02,
	"str%ch",		"%d,[%n,%w]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DGPR(RM))

#define LDRH_PRWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) - GPR(RM);					\
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_PRWL,		0x03,
	"ldr%ch",		"%d,[%n,%w]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

#define STRH_PO_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
                                                                        \
	WRITE_HALF((half_t)GPR_MEM(RD), GPR_EX(RN) - HOFS, _fault);	\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STRH_PO,		0x04,
	"str%ch",		"%d,[%n,-#%h]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDRH_POL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) - HOFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_POL,		0x05,
	"ldr%ch",		"%d,[%n,-#%h]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STRH_POW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) - HOFS;					\
	WRITE_HALF((half_t)GPR_MEM(RD), _addr, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_POW,		0x06,
	"str%ch",		"%d,[%n,-#%h]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDRH_POWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) - HOFS;					\
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_POWL,		0x07,
	"ldr%ch",		"%d,[%n,-#%h]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STRH_PRU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + GPR(RM);					\
	WRITE_HALF((half_t)GPR_MEM(RD), _addr, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STRH_PRU,		0x08,
	"str%ch",		"%d,[%n,%w]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DGPR(RM))

#define LDRH_PRUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) + GPR(RM), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_PRUL,		0x09,
	"ldr%ch",		"%d,[%n,%w]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

#define STRH_PRUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + GPR(RM);					\
	WRITE_HALF((half_t)GPR_MEM(RD), _addr, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_PRUW,		0x0a,
	"str%ch",		"%d,[%n,%w]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DGPR(RM))

#define LDRH_PRUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + GPR(RM);				        \
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_PRUWL,		0x0b,
	"ldr%ch",		"%d,[%n,%w]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

#define STRH_POU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_HALF((half_t)GPR_MEM(RD), GPR_EX(RN) + HOFS, _fault);	\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STRH_POU,		0x0c,
	"str%ch",		"%d,[%n,#%h]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDRH_POUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) + HOFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_POUL,		0x0d,
	"ldr%ch",		"%d,[%n,#%h]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STRH_POUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + HOFS;					\
	WRITE_HALF((half_t)GPR_MEM(RD), _addr, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STRH_POUW,		0x0e,
	"str%ch",		"%d,[%n,#%h]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDRH_POUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + HOFS;					\
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDRH_POUWL,		0x0f,
	"ldr%ch",		"%d,[%n,#%h]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(LDRSB_PSTRSB_P_LINK)

/* FIXME: 0x00: STRSB_PR is invalid... */

#define LDRSB_PRL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN) - GPR(RM), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_PRL,		0x01,
	"ldr%csb",		"%d,[%n,-%w]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x02: STRSB_PRW is invalid, W is implied... */

#define LDRSB_PRWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - GPR(RM);					\
	_result = READ_BYTE(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_PRWL,		0x03,
	"ldr%csb",		"%d,[%n,-%w]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x04: STRSB_PO is invalid... */

#define LDRSB_POL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN) - HOFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_POL,		0x05,
	"ldr%csb",		"%d,[%n,-#%h]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x06: STRSB_POW is invalid, W is implied... */

#define LDRSB_POWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) - HOFS;					\
	_result = READ_BYTE(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_POWL,		0x07,
	"ldr%csb",		"%d,[%n,-#%h]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x08: STRSB_PRU is invalid... */

#define LDRSB_PRUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN) + GPR(RM), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_PRUL,		0x09,
	"ldr%csb",		"%d,[%n,%w]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x0a: STRSB_PRUW is invalid, W is implied... */

#define LDRSB_PRUWL_IMPL						\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + GPR(RM);					\
	_result = READ_BYTE(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_PRUWL,		0x0b,
	"ldr%csb",		"%d,[%n,%w]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x0c: STRSB_POU is invalid... */

#define LDRSB_POUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN) + HOFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_POUL,		0x0d,
	"ldr%csb",		"%d,[%n,#%h]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x0e: STRSB_POUW is invalid, W is implied... */

#define LDRSB_POUWL_IMPL						\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + HOFS; 				        \
	_result = READ_BYTE(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFINST(LDRSB_POUWL,		0x0f,
	"ldr%csb",		"%d,[%n,#%h]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(LDRSH_PSTRSH_P_LINK)

/* FIXME: 0x00: STRSH_PR is invalid... */

#define LDRSH_PRL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) - GPR(RM), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_PRL,		0x01,
	"ldr%csh",		"%d,[%n,-%w]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x02: STRSH_PRW is invalid, W is implied... */

#define LDRSH_PRWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - GPR(RM);					\
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_PRWL,		0x03,
	"ldr%csh",		"%d,[%n,-%w]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x04: STRSH_PO is invalid... */

#define LDRSH_POL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) - HOFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_POL,		0x05,
	"ldr%csh",		"%d,[%n,-#%h]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x06: STRSH_POW is invalid, W is implied... */

#define LDRSH_POWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - HOFS;					\
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_POWL,		0x07,
	"ldr%csh",		"%d,[%n,-#%h]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x08: STRSH_PRU is invalid... */

#define LDRSH_PRUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) + GPR(RM), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_PRUL,		0x09,
	"ldr%csh",		"%d,[%n,%w]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x0a: STRSH_PRUW is invalid, W is implied... */

#define LDRSH_PRUWL_IMPL						\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + GPR(RM);					\
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_PRUWL,		0x0b,
	"ldr%csh",		"%d,[%n,%w]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DGPR(RM))

/* FIXME: 0x0c: STRSH_POU is invalid... */

#define LDRSH_POUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(RN) + HOFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_POUL,		0x0d,
	"ldr%csh",		"%d,[%n,#%h]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x0e: STRSH_POUW is invalid, W is implied... */

#define LDRSH_POUWL_IMPL						\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + HOFS;					\
	_result = READ_HALF(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFINST(LDRSH_POUWL,		0x0f,
	"ldr%csh",		"%d,[%n,#%h]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(MEMIMMPOST_LINK)

#define STR_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(GPR_MEM(RD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - OFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR,			0x00,
	"str%c",		"%d,[%n],-#%o",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_L_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - OFS;					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_L,			0x01,
	"ldr%c",		"%d,[%n],-#%o",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x02: STR_W non-privileged... */

/* FIXME: 0x03: LDR_WL non-privileged... */

#define STR_B_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_BYTE((byte_t)GPR_MEM(RD), GPR_EX(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - OFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_B,			0x04,
	"str%cb",		"%d,[%n],-#%o",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_BL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - OFS;					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_BL,			0x05,
	"ldr%cb",		"%d,[%n],-#%o",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x06: STR_BW non-privileged... */

/* FIXME: 0x07: LDR_BWL non-privileged... */

#define STR_U_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(GPR_MEM(RD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + OFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_U,			0x08,
	"str%c",		"%d,[%n],#%o",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_UL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + OFS;					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_UL,			0x09,
	"ldr%c",		"%d,[%n],#%o",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x0a: STR_UW non-privileged... */

/* FIXME: 0x0b: LDR_UWL non-privileged... */

#define STR_UB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_BYTE((byte_t)GPR_MEM(RD), GPR_EX(RN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + OFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_UB,			0x0c,
	"str%cb",		"%d,[%n],#%o",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_UBL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + OFS;					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_UBL,		0x0d,
	"ldr%cb",		"%d,[%n],#%o",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

/* FIXME: 0x0e: STR_UBW non-privileged... */

/* FIXME: 0x0f: LDR_UBWL non-privileged... */


CONNECT(MEMIMMPRE_LINK)

#define STR_P_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(GPR_MEM(RD), GPR_EX(RN) - OFS, _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_P,			0x00,
	"str%c",		"%d,[%n,-#%o]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(RN) - OFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_PL,			0x01,
	"ldr%c",		"%d,[%n,-#%o]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STR_PW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN) - OFS;					\
	WRITE_WORD(GPR_MEM(RD), _addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_PW,			0x02,
	"str%c",		"%d,[%n,-#%o]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - OFS;					\
	_result = READ_WORD(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_PWL,		0x03,
	"ldr%c",		"%d,[%n,-#%o]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STR_PB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_BYTE((byte_t)GPR_MEM(RD), GPR_EX(RN) - OFS, _fault);	\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_PB,			0x04,
	"str%cb",		"%d,[%n,-#%o]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PBL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(RN) - OFS, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_PBL,		0x05,
	"ldr%cb",		"%d,[%n,-#%o]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STR_PBW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN) - OFS;					\
	WRITE_BYTE((byte_t)GPR_MEM(RD), _addr, _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_PBW,		0x06,
	"str%cb",		"%d,[%n,-#%o]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PBWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - OFS;					\
	_result = READ_BYTE(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_PBWL,		0x07,
	"ldr%cb",		"%d,[%n,-#%o]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STR_PU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        WRITE_WORD(GPR_MEM(RD), GPR_EX(RN) + OFS, _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_PU,			0x08,
	"str%c",		"%d,[%n,#%o]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _result;							\
        enum md_fault_type _fault;					\
									\
        _result = READ_WORD(GPR_EX(RN) + OFS, _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_PUL,		0x09,
	"ldr%c",		"%d,[%n,#%o]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STR_PUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        md_addr_t _addr;						\
									\
        _addr = GPR_EX(RN) + OFS;					\
        WRITE_WORD(GPR_MEM(RD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_PUW,		0x0a,
	"str%c",		"%d,[%n,#%o]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _result;							\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) + OFS;					\
        _result = READ_WORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_PUWL,		0x0b,
	"ldr%c",		"%d,[%n,#%o]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STR_PUB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        WRITE_BYTE((byte_t)GPR_MEM(RD), GPR_EX(RN) + OFS, _fault);	\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_PUB,		0x0c,
	"str%cb",		"%d,[%n,#%o]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PUBL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        byte_t _result;							\
        enum md_fault_type _fault;					\
									\
        _result = READ_BYTE(GPR_EX(RN) + OFS, _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_PUBL,		0x0d,
	"ldr%cb",		"%d,[%n,#%o]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define STR_PUBW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        md_addr_t _addr;						\
									\
        _addr = GPR_EX(RN) + OFS;					\
        WRITE_BYTE((byte_t)GPR_MEM(RD), _addr, _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_PUBW,		0x0e,
	"str%cb",		"%d,[%n,#%o]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCOND, DGPR(RN), DNA)

#define LDR_PUBWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        byte_t _result;							\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) + OFS;					\
        _result = READ_BYTE(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
        SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_PUBWL,		0x0f,
	"ldr%cb",		"%d,[%n,#%o]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(MEMREGPOST_LINK)

#define STR_R_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        WRITE_WORD(GPR_MEM(RD), GPR_EX(RN), _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C));\
      }									\
  }
DEFINST(STR_R,			0x00,
	"str%c",		"%d,[%n],-%m!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        word_t _result;							\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        _result = READ_WORD(GPR_EX(RN), _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, GPR_EX(RN) - SHIFTRM(GPR_RES(RM), /* unused */0, PSR_C));\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RL,			0x01,
	"ldr%c",		"%d,[%n],-%m!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

/* FIXME: STR_RW, 0x02, special priv semantics */

/* FIXME: LDR_RWL, 0x03, special priv semantics */

#define STR_RB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        WRITE_BYTE((byte_t)GPR_MEM(RD), GPR_EX(RN), _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C));\
      }									\
  }
DEFINST(STR_RB,			0x04,
	"str%cb",		"%d,[%n],-%m!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RBL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        word_t _result;							\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        _result = (word_t)READ_BYTE(GPR_EX(RN), _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, GPR_EX(RN) - SHIFTRM(GPR_RES(RM), /* unused */0, PSR_C));\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RBL,		0x05,
	"ldr%cb",		"%d,[%n],-%m!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

/* FIXME: STR_RBW, 0x06, special priv semantics */

/* FIXME: LDR_RBWL, 0x07, special priv semantics */

#define STR_RU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        WRITE_WORD(GPR_MEM(RD), GPR_EX(RN), _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C));\
      }									\
  }
DEFINST(STR_RU,			0x08,
	"str%c",		"%d,[%n],%m!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _result;							\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        _result = READ_WORD(GPR_EX(RN), _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
        _addr = GPR_EX(RN) + SHIFTRM(GPR_RES(RM), /* unused */0, PSR_C);\
									\
        SET_GPR(RN, _addr);						\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RUL,		0x09,
	"ldr%c",		"%d,[%n],%m!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

/* FIXME: STR_RUW, 0x0a, special priv semantics */

/* FIXME: LDR_RUWL, 0x0b, special priv semantics */

#define STR_RUB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        WRITE_BYTE((byte_t)GPR_MEM(RD), GPR_EX(RN), _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C));\
      }									\
  }
DEFINST(STR_RUB,		0x0c,
	"str%cb",		"%d,[%n],%m!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RUBL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _result;							\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        _result = (word_t)READ_BYTE(GPR_EX(RN), _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
        _addr = GPR_EX(RN) + SHIFTRM(GPR_RES(RM), /* unused */0, PSR_C);\
									\
        SET_GPR(RN, _addr);						\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RUBL,		0x0d,
	"ldr%cb",		"%d,[%n],%m!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

/* FIXME: STR_RUBW, 0x0e, special priv semantics */

/* FIXME: LDR_RUBWL, 0x0f, special priv semantics */


CONNECT(MEMREGPRE_LINK)

#define STR_RP_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_WORD(GPR_MEM(RD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_RP,			0x00,
	"str%c",		"%d,[%n, -%m]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        word_t _result;							\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_WORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RPL,		0x01,
	"ldr%c",		"%d,[%n, -%m]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

#define STR_RPW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_WORD(GPR_MEM(RD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_RPW,		0x02,
	"str%c",		"%d,[%n, -%m]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        word_t _result;							\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_WORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RPWL,		0x03,
	"ldr%c",		"%d,[%n, -%m]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

#define STR_RPB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_BYTE((byte_t)GPR_MEM(RD), _addr, _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_RPB,		0x04,
	"str%cb",		"%d,[%n, -%m]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPBL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        byte_t _result;							\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_BYTE(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_RPBL,		0x05,
	"ldr%cb",		"%d,[%n, -%m]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

#define STR_RPBW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_BYTE((byte_t)GPR_MEM(RD), _addr, _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_RPBW,		0x06,
	"str%cb",		"%d,[%n, -%m]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPBWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        byte_t _result;							\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_BYTE(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
        SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_RPBWL,		0x07,
	"ldr%cb",		"%d,[%n, -%m]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

#define STR_RPU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_WORD(GPR_MEM(RD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_RPU,		0x08,
	"str%c",		"%d,[%n, %m]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
        word_t _result;							\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_WORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RPUL,		0x09,
	"ldr%c",		"%d,[%n, %m]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

#define STR_RPUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        md_addr_t _addr;						\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        _addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_WORD(GPR_MEM(RD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_RPUW,		0x0a,
	"str%c",		"%d,[%n, %m]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        md_addr_t _addr;						\
        word_t _result;							\
        enum md_fault_type _fault;					\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
        _addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_WORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
        SET_GPR(RD, _result);						\
      }									\
  }
DEFINST(LDR_RPUWL,		0x0b,
	"ldr%c",		"%d,[%n, %m]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

#define STR_RPUB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        /* register shift amounts not allowed for ld/st (THANK YOU!) */	\
        if (SHIFT_REG)							\
          DECLARE_FAULT(md_fault_unimpl);				\
									\
	_addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_BYTE((byte_t)GPR_MEM(RD), _addr, _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STR_RPUB,		0x0c,
	"str%cb",		"%d,[%n, %m]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPUBL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        byte_t _result;							\
	md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_BYTE(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_RPUBL,		0x0d,
	"ldr%cb",		"%d,[%n, %m]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD), DNA, DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))

#define STR_RPUBW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        md_addr_t _addr;						\
									\
        _addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        WRITE_BYTE((byte_t)GPR_MEM(RD), _addr, _fault);			\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STR_RPUBW,		0x0e,
	"str%cb",		"%d,[%n, %m]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DGPR(RD), /**/DCONDSH, DGPR(RN), DGPR(RM))

#define LDR_RPUBWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        byte_t _result;							\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C);	\
        _result = READ_BYTE(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
        SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFINST(LDR_RPUBWL,		0x0f,
	"ldr%cb",		"%d,[%n, %m]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DGPR(RD),DGPR(RN),DNA,	DNA, /**/DCONDSH, DGPR(RN), DGPR(RM))


CONNECT(BLKPOST_LINK)

#define STM_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2) + 4;			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_MEM(_i), _addr, _fault);			\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(STM,			0x00,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_L_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
        word_t _result;							\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2) + 4;			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_L,			0x01,
	"ldm%c%a",		"%n,%R",
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define STM_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _first = TRUE;						\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2) + 4;			\
	_wbaddr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_BASE(_i), _addr, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
									\
		/* done processing first register */			\
		_first = FALSE;						\
	      }								\
	  }								\
	SET_GPR(RN, _wbaddr);						\
      }									\
  }
DEFINST(STM_W,			0x02,
	"stm%c%a",		"%n!,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_WL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
        word_t _result;							\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2) + 4;			\
	_wbaddr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	SET_GPR(RN, _wbaddr);						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_WL,			0x03,
	"ldm%c%a",		"%n!,%R",
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#if 0

/* STM_S, 0x04, TODO... */

DEFINST(STM_S,			0x04,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)


/* LDM_SL, 0x05, TODO... */

DEFINST(LDM_SL,			0x05,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

/* STM_SW, 0x06, TODO... */

DEFINST(STM_SW,			0x06,
	"stm%c%a",		"%n!,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)


/* LDM_SWL, 0x07, TODO... */

DEFINST(LDM_SWL,			0x07,
	"stm%c%a",		"%n!,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)
#endif

#define STM_U_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN);						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_MEM(_i), _addr, _fault);			\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(STM_U,			0x08,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_UL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
        word_t _result;							\
									\
	_addr = GPR_EX(RN);						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_UL,			0x09,
	"ldm%c%a",		"%n,%R",
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define STM_UW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _first = TRUE;						\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
									\
	_addr = GPR_EX(RN);						\
	_wbaddr = GPR(RN) + (ONES(REGLIST) << 2);			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_BASE(_i), _addr, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
									\
		/* done processing first register */			\
		_first = FALSE;						\
	      }								\
	  }								\
	SET_GPR(RN, _wbaddr);						\
      }									\
  }
DEFINST(STM_UW,			0x0a,
	"stm%c%a",		"%n!,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_UWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
        word_t _result;							\
									\
	_addr = GPR_EX(RN);						\
	_wbaddr = GPR_EX(RN) + (ONES(REGLIST) << 2);			\
	SET_GPR(RN, _wbaddr);						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_UWL,		0x0b,
	"ldm%c%a",		"%n!,%R", 
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#if 0

/* STM_US, 0x0c, TODO... */

DEFINST(STM_US,			0x0c,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

/* LDM_USL, 0x0d, TODO... */

DEFINST(LDM_USL,			0x0d,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

/* STM_USW, 0x0e, TODO... */

DEFINST(STM_USW,			0x0e,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)


/* LDM_USWL, 0x0f, TODO... */

DEFINST(LDM_USWL,			0x0f,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)
#endif


CONNECT(BLKPRE_LINK)

#define STM_P_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_MEM(_i), _addr, _fault);			\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(STM_P,			0x00,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_PL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
        word_t _result;							\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_PL,			0x01,
	"ldm%c%a",		"%n,%R",
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define STM_PW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _first = TRUE;						\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	_wbaddr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_BASE(_i), _addr, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
									\
		/* done processing first register */			\
		_first = FALSE;						\
	      }								\
	  }								\
	SET_GPR(RN, _wbaddr);						\
      }									\
  }
DEFINST(STM_PW,			0x02,
	"stm%c%a",		"%n!,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_PWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
        word_t _result;							\
									\
	_addr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	_wbaddr = GPR_EX(RN) - (ONES(REGLIST) << 2);			\
	SET_GPR(RN, _wbaddr);						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_PWL,       		0x03,
	"ldm%c%a",		"%n!,%R",
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

/* STM_PS, 0x04, TODO... */

/* LDM_PSL, 0x05, TODO... */

/* STM_PSW, 0x06, TODO... */

/* LDM_PSWL, 0x07, TODO... */

#define STM_PU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN) + 4;						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_MEM(_i), _addr, _fault);			\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(STM_PU,			0x08,
	"stm%c%a",		"%n,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_PUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr;						\
        word_t _result;							\
									\
	_addr = GPR_EX(RN) + 4;						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_PUL,       		0x09,
	"ldm%c%a",		"%n,%R",
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define STM_PUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _first = TRUE;						\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
									\
	_addr = GPR_EX(RN) + 4;						\
	_wbaddr = GPR_EX(RN) + (ONES(REGLIST) << 2);			\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		WRITE_WORD(GPR_BASE(_i), _addr, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		_addr += 4;						\
									\
		/* done processing first register */			\
		_first = FALSE;						\
	      }								\
	  }								\
	SET_GPR(RN, _wbaddr);						\
      }									\
  }
DEFINST(STM_PUW,       		0x0a,
	"stm%c%a",		"%n!,%R",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

#define LDM_PUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i;								\
        enum md_fault_type _fault;					\
	md_addr_t _addr, _wbaddr;					\
        word_t _result;							\
									\
	_addr = GPR_EX(RN) + 4;						\
	_wbaddr = GPR_EX(RN) + (ONES(REGLIST) << 2);			\
	SET_GPR(RN, _wbaddr);						\
	for (_i=0; _i < 16; _i++)					\
	  {								\
	    if (REGLIST & (1 << _i))					\
	      {								\
		/* store reg(_i) */					\
		_result = READ_WORD(_addr & ~3, _fault);		\
		if (_fault != md_fault_none)				\
		  DECLARE_FAULT(_fault);				\
		SET_GPR(_i, _result);					\
		_addr += 4;						\
	      }								\
	  }								\
      }									\
  }
DEFINST(LDM_PUWL,		0x0b,
	"ldm%c%a",		"%n!,%R",
	RdPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DNA, DNA, DNA, DNA)

/* STM_PUS, 0x0c, TODO... */

/* LDM_PUSL, 0x0d, TODO... */

/* STM_PUSW, 0x0e, TODO... */

/* LDM_PUSWL, 0x0f, TODO... */


CONNECT(CPROC_LINK)

DEFLINK(FPA_LINK, 0x01, "fpa_link", 4, 0x01)


CONNECT(FPA_LINK)

DEFLINK(CPDO_LINK, 0x00, "cpdo_link", 20, 0x0f)

DEFLINK(CPRTCMF_LINK, 0x01, "cprtcmf_link", 12, 0x0f)


CONNECT(CPRTCMF_LINK)

DEFLINK(CPRT_CDP_LINK, 0x0e00, "cprt_cdp_link", 4, 0x01)

DEFLINK(CMF_LINK, 0x0f, "cmf_link", 21, 0x07)


/* FP coprocessor data operations (CPDO) */

CONNECT(CPDO_LINK)

DEFLINK(ADFMVF_LINK, 0x00, "adfmvf_link", 15, 0x01)

DEFLINK(MUFMNF_LINK, 0x01, "mufmnf_link", 15, 0x01)

DEFLINK(SUFABS_LINK, 0x02, "sufabs_link", 15, 0x01)

DEFLINK(RSFRND_LINK, 0x03, "rsfrnd_link", 15, 0x01)

DEFLINK(DVFSQT_LINK, 0x04, "dvfsqt_link", 15, 0x01)

DEFLINK(RDFLOG_LINK, 0x05, "rdflog_link", 15, 0x01)

DEFLINK(POWLGN_LINK, 0x06, "powlgn_link", 15, 0x01)

DEFLINK(RPWEXP_LINK, 0x07, "rpwexp_link", 15, 0x01)

DEFLINK(RMFSIN_LINK, 0x08, "rmfsin_link", 15, 0x01)

DEFLINK(FMLCOS_LINK, 0x09, "fmlcos_link", 15, 0x01)

DEFLINK(FDVTAN_LINK, 0x0a, "fdvtan_link", 15, 0x01)

DEFLINK(FRDASN_LINK, 0x0b, "frdasn_link", 15, 0x01)

DEFLINK(POLACS_LINK, 0x0c, "polacs_link", 15, 0x01)

DEFLINK(UNDATN_LINK, 0x0d, "undatn_link", 15, 0x01)

DEFLINK(UNDURD_LINK, 0x0e, "undurd_link", 15, 0x01)

DEFLINK(UNDNRM_LINK, 0x0f, "undnrm_link", 15, 0x01)


CONNECT(ADFMVF_LINK)

DEFLINK(ADFADFI_LINK, 0x00, "adfadfi_link", 3, 0x01)

DEFLINK(MVFMVFI_LINK, 0x01, "mvfmvfi_link", 3, 0x01)


CONNECT(MUFMNF_LINK)

DEFLINK(MUFMUFI_LINK, 0x00, "mufmufi_link", 3, 0x01)

DEFLINK(MNFMNFI_LINK, 0x01, "mnfmnfi_link", 3, 0x01)


CONNECT(SUFABS_LINK)

DEFLINK(SUFSUFI_LINK, 0x00, "sufsufi_link", 3, 0x01)

DEFLINK(ABSABSI_LINK, 0x01, "absabsi_link", 3, 0x01)


CONNECT(RSFRND_LINK)

DEFLINK(RSFRSFI_LINK, 0x00, "rsfrsfi_link", 3, 0x01)

DEFLINK(RNDRNDI_LINK, 0x01, "rndrndi_link", 3, 0x01)


CONNECT(DVFSQT_LINK)

DEFLINK(DVFDVFI_LINK, 0x00, "dvfdvfi_link", 3, 0x01)

DEFLINK(SQTSQTI_LINK, 0x01, "sqtsqti_link", 3, 0x01)


CONNECT(RDFLOG_LINK)

DEFLINK(RDFRDFI_LINK, 0x00, "rdfrdfi_link", 3, 0x01)

DEFLINK(LOGLOGI_LINK, 0x01, "loglogi_link", 3, 0x01)


CONNECT(POWLGN_LINK)

DEFLINK(POWPOWI_LINK, 0x00, "powpowi_link", 3, 0x01)

DEFLINK(LGNLGNI_LINK, 0x01, "lgnlgni_link", 3, 0x01)


CONNECT(RPWEXP_LINK)

DEFLINK(RPWRPWI_LINK, 0x00, "rpwrpwi_link", 3, 0x01)

DEFLINK(EXPEXPI_LINK, 0x01, "expexpi_link", 3, 0x01)


CONNECT(RMFSIN_LINK)

DEFLINK(RMFRMFI_LINK, 0x00, "rmfrmfi_link", 3, 0x01)

DEFLINK(SINSINI_LINK, 0x01, "sinsini_link", 3, 0x01)


CONNECT(FMLCOS_LINK)

DEFLINK(FMLFMLI_LINK, 0x00, "fmlfmli_link", 3, 0x01)

DEFLINK(COSCOSI_LINK, 0x01, "coscosi_link", 3, 0x01)


CONNECT(FDVTAN_LINK)

DEFLINK(FDVFDVI_LINK, 0x00, "fdvfdvi_link", 3, 0x01)

DEFLINK(TANTANI_LINK, 0x01, "tantani_link", 3, 0x01)


CONNECT(FRDASN_LINK)

DEFLINK(FRDFRDI_LINK, 0x00, "frdfrdi_link", 3, 0x01)

DEFLINK(ASNASNI_LINK, 0x01, "asnasni_link", 3, 0x01)


CONNECT(POLACS_LINK)

DEFLINK(POLPOLI_LINK, 0x00, "polpoli_link", 3, 0x01)

DEFLINK(ACSACSI_LINK, 0x01, "acsacsi_link", 3, 0x01)


CONNECT(UNDATN_LINK)

DEFLINK(ATNATNI_LINK, 0x01, "atnatni_link", 3, 0x01)


CONNECT(UNDURD_LINK)

DEFLINK(URDURDI_LINK, 0x01, "urdurdi_link", 3, 0x01)


CONNECT(UNDNRM_LINK)

DEFLINK(NRMNRMI_LINK, 0x01, "nrmnrmi_link", 3, 0x01)


CONNECT(ADFADFI_LINK)

#define ADF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) + FPR(FM));					\
      }									\
  }
DEFINST(ADF,			0x00,
	"adf%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define ADFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) + FPIMM);					\
      }									\
  }
DEFINST(ADFI,			0x01,
	"adf%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(MVFMVFI_LINK)

#define MVF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FM));						\
      }									\
  }
DEFINST(MVF,			0x00,
	"mvf%c%t%r",		"%D,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define MVFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPIMM);						\
      }									\
  }
DEFINST(MVFI,			0x01,
	"mvf%c%t%r",		"%D,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(MUFMUFI_LINK)

#define MUF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) * FPR(FM));					\
      }									\
  }
DEFINST(MUF,			0x00,
	"muf%c%t%r",		"%D,%N,%M",
	FloatMULT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define MUFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) * FPIMM);					\
      }									\
  }
DEFINST(MUFI,			0x01,
	"muf%c%t%r",		"%D,%N,#%I",
	FloatMULT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(MNFMNFI_LINK)

#define MNF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, -FPR(FM));						\
      }									\
  }
DEFINST(MNF,			0x00,
	"mnf%c%t%r",		"%D,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define MNFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, -FPIMM);						\
      }									\
  }
DEFINST(MNFI,			0x01,
	"mnf%c%t%r",		"%D,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(SUFSUFI_LINK)

#define SUF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) - FPR(FM));					\
      }									\
  }
DEFINST(SUF,			0x00,
	"suf%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define SUFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) - FPIMM);					\
      }									\
  }
DEFINST(SUFI,			0x01,
	"suf%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(ABSABSI_LINK)

#define ABS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, fabs(FPR(FM)));					\
      }									\
  }
DEFINST(ABS,			0x00,
	"abs%c%t%r",		"%D,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define ABSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, fabs(FPIMM));					\
      }									\
  }
DEFINST(ABSI,			0x01,
	"abs%c%t%r",		"%D,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(RSFRSFI_LINK)

#define RSF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FM) - FPR(FN));					\
      }									\
  }
DEFINST(RSF,			0x00,
	"rsf%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define RSFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPIMM - FPR(FN));					\
      }									\
  }
DEFINST(RSFI,			0x01,
	"rsf%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(RNDRNDI_LINK)

#define RND_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: need to track current rounding mode... */		\
	SET_FPR(FD, rint(FPR(FM)));					\
      }									\
  }
DEFINST(RND,			0x00,
	"rnd%c%t%r",		"%D,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define RNDI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: need to track current rounding mode... */		\
	SET_FPR(FD, rint(FPIMM));					\
      }									\
  }
DEFINST(RNDI,			0x01,
	"rnd%c%t%r",		"%D,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(DVFDVFI_LINK)

#define DVF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) / FPR(FM));					\
      }									\
  }
DEFINST(DVF,			0x00,
	"dvf%c%t%r",		"%D,%N,%M",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define DVFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) / FPIMM);					\
      }									\
  }
DEFINST(DVFI,			0x01,
	"dvf%c%t%r",		"%D,%N,#%I",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(SQTSQTI_LINK)

#define SQT_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, sqrt(FPR(FM)));					\
      }									\
  }
DEFINST(SQT,			0x00,
	"sqt%c%t%r",		"%D,%M",
	FloatSQRT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define SQTI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, sqrt(FPIMM));					\
      }									\
  }
DEFINST(SQTI,			0x01,
	"sqt%c%t%r",		"%D,#%I",
	FloatSQRT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(RDFRDFI_LINK)

#define RDF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FM) / FPR(FN));					\
      }									\
  }
DEFINST(RDF,			0x00,
	"rdf%c%t%r",		"%D,%N,%M",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define RDFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPIMM / FPR(FN));					\
      }									\
  }
DEFINST(RDFI,			0x01,
	"rdf%c%t%r",		"%D,%N,#%I",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(LOGLOGI_LINK)

#define LOG_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, log10(FPR(FM)));					\
      }									\
  }
DEFINST(LOG,			0x00,
	"log%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define LOGI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, log10(FPIMM));					\
      }									\
  }
DEFINST(LOGI,			0x01,
	"log%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(POWPOWI_LINK)

#define POW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, pow(FPR(FN), FPR(FM)));				\
      }									\
  }
DEFINST(POW,			0x00,
	"pow%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define POWI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, pow(FPR(FN), FPIMM));				\
      }									\
  }
DEFINST(POWI,			0x01,
	"pow%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(LGNLGNI_LINK)

#define LGN_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, log(FPR(FM)));					\
      }									\
  }
DEFINST(LGN,			0x00,
	"lgn%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define LGNI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, log(FPIMM));					\
      }									\
  }
DEFINST(LGNI,			0x01,
	"lgn%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(RPWRPWI_LINK)

#define RPW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, pow(FPR(FM), FPR(FN)));				\
      }									\
  }
DEFINST(RPW,			0x00,
	"rpw%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define RPWI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, pow(FPIMM, FPR(FN)));				\
      }									\
  }
DEFINST(RPWI,			0x01,
	"rpw%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(EXPEXPI_LINK)

#define EXP_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, exp(FPR(FM)));					\
      }									\
  }
DEFINST(EXP,			0x00,
	"exp%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define EXPI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, exp(FPIMM));					\
      }									\
  }
DEFINST(EXPI,			0x01,
	"exp%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(RMFRMFI_LINK)

#define RMF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, drem(FPR(FN), FPR(FM)));				\
      }									\
  }
DEFINST(RMF,			0x00,
	"rmf%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define RMFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, drem(FPR(FN), FPIMM));				\
      }									\
  }
DEFINST(RMFI,			0x01,
	"rmf%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(SINSINI_LINK)

#define SIN_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, sin(FPR(FM)));					\
      }									\
  }
DEFINST(SIN,			0x00,
	"sin%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define SINI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, sin(FPIMM));					\
      }									\
  }
DEFINST(SINI,			0x01,
	"sin%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(FMLFMLI_LINK)

#define FML_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) * FPR(FM));					\
      }									\
  }
DEFINST(FML,			0x00,
	"fml%c%t%r",		"%D,%N,%M",
	FloatMULT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define FMLI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) * FPIMM);					\
      }									\
  }
DEFINST(FMLI,			0x01,
	"fml%c%t%r",		"%D,%N,#%I",
	FloatMULT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(COSCOSI_LINK)

#define COS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, cos(FPR(FM)));					\
      }									\
  }
DEFINST(COS,			0x00,
	"cos%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define COSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, cos(FPIMM));					\
      }									\
  }
DEFINST(COSI,			0x01,
	"cos%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(FDVFDVI_LINK)

#define FDV_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) / FPR(FM));					\
      }									\
  }
DEFINST(FDV,			0x00,
	"fdv%c%t%r",		"%D,%N,%M",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define FDVI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FN) / FPIMM);					\
      }									\
  }
DEFINST(FDVI,			0x01,
	"fdv%c%t%r",		"%D,%N,#%I",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(TANTANI_LINK)

#define TAN_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, tan(FPR(FM)));					\
      }									\
  }
DEFINST(TAN,			0x00,
	"tan%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define TANI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, tan(FPIMM));					\
      }									\
  }
DEFINST(TANI,			0x01,
	"tan%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(FRDFRDI_LINK)

#define FRD_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPR(FM) / FPR(FN));					\
      }									\
  }
DEFINST(FRD,			0x00,
	"frd%c%t%r",		"%D,%N,%M",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define FRDI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, FPIMM / FPR(FN));					\
      }									\
  }
DEFINST(FRDI,			0x01,
	"frd%c%t%r",		"%D,%N,#%I",
	FloatDIV,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(ASNASNI_LINK)

#define ASN_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, asin(FPR(FM)));					\
      }									\
  }
DEFINST(ASN,			0x00,
	"asn%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define ASNI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, asin(FPIMM));					\
      }									\
  }
DEFINST(ASNI,			0x01,
	"asn%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(POLPOLI_LINK)

#define POL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, atan2(FPR(FN), FPR(FM)));				\
      }									\
  }
DEFINST(POL,			0x00,
	"pol%c%t%r",		"%D,%N,%M",
	FloatSQRT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DFPR(FM), DNA)

#define POLI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, atan2(FPR(FN), FPIMM));				\
      }									\
  }
DEFINST(POLI,			0x01,
	"pol%c%t%r",		"%D,%N,#%I",
	FloatSQRT,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FN), DNA, DNA)


CONNECT(ACSACSI_LINK)

#define ACS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, acos(FPR(FM)));					\
      }									\
  }
DEFINST(ACS,			0x00,
	"acs%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define ACSI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, acos(FPIMM));					\
      }									\
  }
DEFINST(ACSI,			0x01,
	"acs%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(ATNATNI_LINK)

#define ATN_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, atan(FPR(FM)));					\
      }									\
  }
DEFINST(ATN,			0x00,
	"atn%c%t%r",		"%D,%N,%M",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define ATNI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FD, atan(FPIMM));					\
      }									\
  }
DEFINST(ATNI,			0x01,
	"atn%c%t%r",		"%D,%N,#%I",
	FloatADD,		F_FCOMP,
	DFPR(FD), DNA, DNA,	DCOND, DNA, DNA, DNA)


CONNECT(URDURDI_LINK)

#define FURD_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: how does this work??? */				\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(FURD,			0x00,
	"urd%c%t%r",		"%D,%M",
	FloatADD,		F_FCOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define FURDI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: how does this work??? */				\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(FURDI,			0x01,
	"urd%c%t%r",		"%D,#%I",
	FloatADD,		F_FCOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(NRMNRMI_LINK)

#define NRM_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: how does this work??? */				\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(NRM,			0x00,
	"nrm%c%t%r",		"%D,%M",
	FloatADD,		F_FCOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define NRMI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: how does this work??? */				\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(NRMI,			0x01,
	"nrm%c%t%r",		"%D,#%I",
	FloatADD,		F_FCOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


/* FP coprocessor register transfer (CPRT) */

CONNECT(CPRT_CDP_LINK)

DEFLINK(CDP_LINK, 0x00, "cdp_link", 4, 0x01)

DEFLINK(CPRT_LINK, 0x01, "cprt_link", 20, 0x0f)


CONNECT(CDP_LINK)

	/* FIXME: Work more on this CDP instruction !!!! */
	
#define CDP_IMPL						\
	{							\
	  /* what exactly does this do?? */			\
	}							\
	
/* need to fix this instruction definition */

DEFINST(CDP,			0x00,
	"cdp%c",		"%P, %p, c%d, c%n, c%w, {%g}",
	FloatADD,		F_FCOMP,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

CONNECT(CPRT_LINK)

#define FLT_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPR(FN, (dfloat_t)(sword_t)GPR_MEM(RD));			\
      }									\
  }
DEFINST(FLT,			0x00,
	"flt%c%t%r",		"%N,%d",
	FloatADD,		F_FCOMP,
	DFPR(FN), DNA, DNA,	DCOND, DGPR(RD), DNA, DNA)

#define FIX_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, (word_t)FPR(FM));					\
      }									\
  }
DEFINST(FIX,			0x01,
	"fix%c%r",		"%d,%M",
	FloatADD,		F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DFPR(FM), DNA, DNA)

#define WFS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_FPSR(GPR_MEM(RD));						\
      }									\
  }
DEFINST(WFS,			0x02,
	"wfs%c",		"%d",
	IntALU,			F_ICOMP,
	DFPSR, DNA, DNA,	DCOND, DGPR(RD), DNA, DNA)

#define RFS_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	SET_GPR(RD, FPSR);						\
      }									\
  }
DEFINST(RFS,			0x03,
	"rfs%c",		"%d",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DFPSR, DNA, DNA)

#define WFC_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: supervisory mode only... */				\
	SET_FPSR(GPR_MEM(RD));						\
      }									\
  }
DEFINST(WFC,			0x04,
	"wfc%c",		"%d",
	IntALU,			F_ICOMP,
	DFPSR, DNA, DNA,	DCOND, DGPR(RD), DNA, DNA)

#define RFC_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: supervisory mode only... */				\
	SET_GPR(RD, FPSR);						\
      }									\
  }
DEFINST(RFC,			0x05,
	"rfc%c",		"%d",
	IntALU,			F_ICOMP,
	DGPR(RD), DNA, DNA,	DCOND, DFPSR, DNA, DNA)


CONNECT(CMF_LINK)

DEFLINK(CMFCMFI_LINK, 0x04, "cmfcmfi_link", 3, 0x01)

DEFLINK(CNFCNFI_LINK, 0x05, "cnfcnfi_link", 3, 0x01)

DEFLINK(CMFECMFEI_LINK, 0x06, "cmfecmfei_link", 3, 0x01)

DEFLINK(CNFECNFEI_LINK, 0x07, "cnfecnfei_link", 3, 0x01)


CONNECT(CMFCMFI_LINK)

#define CMF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = FPR(FM);				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CMF,			0x00,
	"cmf%c",		"%N,%M",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DFPR(FM), DNA)

#define CMFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = FPIMM;				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CMFI,			0x01,
	"cmf%c",		"%N,#%I",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DNA, DNA)


CONNECT(CNFCNFI_LINK)

#define CNF_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = -FPR(FM);				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CNF,			0x00,
	"cnf%c",		"%N,%M",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DFPR(FM), DNA)

#define CNFI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = -FPIMM;				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CNFI,			0x01,
	"cnf%c",		"%N,#%I",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DNA, DNA)


CONNECT(CMFECMFEI_LINK)

#define CMFE_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = FPR(FM);				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	if (nanfn || nanfm)						\
	  /* DECLARE_FAULT(md_fault_invalid) */;			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CMFE,			0x00,
	"cmfe%c",		"%N,%M",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DFPR(FM), DNA)

#define CMFEI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = FPIMM;				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	if (nanfn || nanfm)						\
	  /* DECLARE_FAULT(md_fault_invalid) */;			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CMFEI,			0x01,
	"cmfe%c",		"%N,#%I",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DNA, DNA)


CONNECT(CNFECNFEI_LINK)

#define CNFE_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = -FPR(FM);				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	if (nanfn || nanfm)						\
	  /* DECLARE_FAULT(md_fault_invalid) */;			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CNFE,			0x00,
	"cnfe%c",		"%N,%M",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DFPR(FM), DNA)

#define CNFEI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	dfloat_t fn = FPR(FN), fm = -FPIMM;				\
	int nanfn = isnan(fn), nanfm = isnan(fm);			\
									\
	if (nanfn || nanfm)						\
	  /* DECLARE_FAULT(md_fault_invalid) */;			\
									\
	SET_PSR_N(fn < fm);						\
	SET_PSR_Z(fn == fm);						\
	SET_PSR_C(fn >= fm);						\
	SET_PSR_V(nanfn || nanfm);					\
      }									\
  }
DEFINST(CNFEI,			0x01,
	"cnfe%c",		"%N,#%I",
	FloatADD,		F_FCOMP,
	DPSR, DNA, DNA,		DCOND, DFPR(FN), DNA, DNA)


CONNECT(CDXPOST_LINK)

DEFLINK(LDFSTFPOST_LINK, 0x01, "ldfstfpost_link", 20, 0x0f)

DEFLINK(LFMSFMPOST_LINK, 0x02, "lfmsfmpost_link", 20, 0x0b)


CONNECT(CDXPRE_LINK)

DEFLINK(LDFSTFPRE_LINK, 0x01, "ldfstfpre_link", 20, 0x0f)

DEFLINK(LFMSFMPRE_LINK, 0x02, "lfmsfmpre_link", 20, 0x0b)


CONNECT(LDFSTFPOST_LINK)

/* DEFLINK(STFSSTFD_LINK, 0x00, "stfsstfd_link", 15, 0x01) */

/* DEFLINK(LDFS_LLDFD_L_LINK, 0x01, "ldfs_lldfd_l_link", 15, 0x01) */

DEFLINK(STFS_WSTFD_W_LINK, 0x02, "stfs_wstfd_w_link", 15, 0x01)

DEFLINK(LDFS_WLLDFD_WL_LINK, 0x03, "ldfs_wlldfd_wl_link", 15, 0x01)

DEFLINK(STFE_WSTFP_W_LINK, 0x06, "stfe_wstfp_w_link", 15, 0x01)

DEFLINK(LDFE_WLLDFP_WL_LINK, 0x07, "ldfe_wlldfp_wl_link", 15, 0x01)

/* DEFLINK(STFS_USTFD_U_LINK, 0x08, "stfs_ustfd_u_link", 15, 0x01) */

/* DEFLINK(LDFS_ULLDFD_UL_LINK, 0x09, "ldfs_ulldfd_ul_link", 15, 0x01) */

DEFLINK(STFS_UWSTFD_UW_LINK, 0x0a, "stfs_uwstfd_uw_link", 15, 0x01)

DEFLINK(LDFS_UWLLDFD_UWL_LINK, 0x0b, "ldfs_uwlldfd_uwl_link", 15, 0x01)

DEFLINK(STFE_UWSTFP_UW_LINK, 0x0e, "stfe_uwstfp_uw_link", 15, 0x01)

DEFLINK(LDFE_UWLLDFP_UWL_LINK, 0x0f, "ldfe_uwlldfp_uwl_link", 15, 0x01)


CONNECT(STFS_WSTFD_W_LINK)

#define STFS_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(FPR_W(FD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - FPOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFS_W,			0x00,
	"stf%cs",		"%D,[%n],-#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFD_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - FPOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFD_W,			0x01,

	"stf%cd",		"%D,[%n],-#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)


CONNECT(LDFS_WLLDFD_WL_LINK)

#define LDFS_WL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - FPOFS;					\
									\
	SET_FPR_W(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFS_WL,		0x00,
	"ldf%cs",		"%D,[%n],-#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFD_WL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_QWORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - FPOFS;					\
									\
	SET_FPR_Q(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFD_WL,		0x01,
	
	"ldf%cd",		"%D,[%n],-#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(STFE_WSTFP_W_LINK)

#define STFE_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	/* FIXME: need to store an extended word here... */		\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - FPOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFE_W,			0x00,
	"stf%ce",		"%D,[%n],-#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFP_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(STFP_W,			0x01,
	"stf%cp",		"%D,[%n],-#%O",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LDFE_WLLDFP_WL_LINK)

#define LDFE_WL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	/* FIXME: need to load an extended word here... */		\
	_result = READ_QWORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) - FPOFS;					\
									\
	SET_FPR_Q(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFE_WL,		0x00,
	"ldf%ce",		"%D,[%n],-#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFP_WL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(LDFP_WL,		0x01,
	"ldf%cp",		"%D,[%n],-#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(STFS_UWSTFD_UW_LINK)

#define STFS_UW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(FPR_W(FD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + FPOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFS_UW,		0x00,
	"stf%cs",		"%D,[%n],#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFD_UW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + FPOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFD_UW,		0x01,
	"stf%cd",		"%D,[%n],#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)


CONNECT(LDFS_UWLLDFD_UWL_LINK)

#define LDFS_UWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + FPOFS;					\
									\
	SET_FPR_W(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFS_UWL,		0x00,
	"ldf%cs",		"%D,[%n],#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFD_UWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_QWORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + FPOFS;					\
									\
	SET_FPR_Q(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFD_UWL,		0x01,
	"ldf%cd",		"%D,[%n],#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(STFE_UWSTFP_UW_LINK)

#define STFE_UW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	/* FIXME: need to load an extended word here... */		\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + FPOFS;					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFE_UW,		0x00,
	"stf%ce",		"%D,[%n],#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFP_UW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(STFP_UW,		0x01,
	"stf%cp",		"%D,[%n],#%O",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LDFE_UWLLDFP_UWL_LINK)

#define LDFE_UWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	/* FIXME: need to load an extended word here... */		\
	_result = READ_QWORD(GPR_EX(RN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	_addr = GPR_EX(RN) + FPOFS;					\
									\
	SET_FPR_Q(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFE_UWL,		0x00,
	"ldf%ce",		"%D,[%n],#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFP_UWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(LDFP_UWL,		0x01,
	"ldf%cp",		"%D,[%n],#%O",
	RdPort,			F_MEM|F_LOAD|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LDFSTFPRE_LINK)

DEFLINK(STFS_PSTFD_P_LINK, 0x00, "stfs_pstfd_p_link", 15, 0x01)

DEFLINK(LDFS_PLLDFD_PL_LINK, 0x01, "ldfs_plldfd_pl_link", 15, 0x01)

DEFLINK(STFS_PWSTFD_PW_LINK, 0x02, "stfs_pwstfd_pw_link", 15, 0x01)

DEFLINK(LDFS_PWLLDFD_PWL_LINK, 0x03, "ldfs_pwlldfd_pwl_link", 15, 0x01)

DEFLINK(STFE_PSTFP_P_LINK, 0x04, "stfe_pstfp_p_link", 15, 0x01)

DEFLINK(LDFE_PLLDFP_PL_LINK, 0x05, "ldfe_plldfp_pl_link", 15, 0x01)

DEFLINK(STFE_PWSTFP_PW_LINK, 0x06, "stfe_pwstfp_pw_link", 15, 0x01)

DEFLINK(LDFE_PWLLDFP_PWL_LINK, 0x07, "ldfe_pwlldfp_pwl_link", 15, 0x01)

DEFLINK(STFS_PUSTFD_PU_LINK, 0x08, "stfs_pustfd_pu_link", 15, 0x01)

DEFLINK(LDFS_PULLDFD_PUL_LINK, 0x09, "ldfs_pulldfd_pul_link",15,0x01)

DEFLINK(STFS_PUWSTFD_PUW_LINK, 0x0a, "stfs_puwstfd_puw_link", 15, 0x01)

DEFLINK(LDFS_PUWLLDFD_PUWL_LINK, 0x0b, "ldfs_puwlldfd_puwl_link", 15, 0x01)

DEFLINK(STFE_PUSTFP_PU_LINK, 0x0c, "stfe_pustfp_pu_link", 15, 0x01)

DEFLINK(LDFE_PULLDFP_PUL_LINK, 0x0d, "ldfe_pulldfp_pul_link", 15, 0x01)

DEFLINK(STFE_PUWSTFP_PUW_LINK, 0x0e, "stfe_puwstfp_puw_link", 15, 0x01)

DEFLINK(LDFE_PUWLLDFP_PUWL_LINK, 0x0f, "ldfe_puwlldfp_puwl_link", 15, 0x01)


CONNECT(STFS_PSTFD_P_LINK)

#define STFS_P_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(FPR_W(FD), GPR_EX(RN) - FPOFS, _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STFS_P,			0x00,
	"stf%cs",		"%D,[%n,-#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFD_P_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(RN) - FPOFS, _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STFD_P,			0x01,
	"stf%cd",		"%D,[%n,-#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(RN), DNA)


CONNECT(LDFS_PLLDFD_PL_LINK)

#define LDFS_PL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(RN) - FPOFS, _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_FPR_W(FD, _result);						\
      }									\
  }
DEFINST(LDFS_PL,		0x00,
	"ldf%cs",		"%D,[%n,-#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFD_PL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_QWORD(GPR_EX(RN) - FPOFS, _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_FPR_Q(FD, _result);						\
      }									\
  }
DEFINST(LDFD_PL,		0x01,
	"ldf%cd",		"%D,[%n,-#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(STFS_PWSTFD_PW_LINK)

#define STFS_PW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	WRITE_WORD(FPR_W(FD), _addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFS_PW,		0x00,
	"stf%cs",		"%D,[%n,-#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFD_PW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	WRITE_QWORD(FPR_Q(FD), _addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFD_PW,		0x01,
	"stf%cd",		"%D,[%n,-#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)


CONNECT(LDFS_PWLLDFD_PWL_LINK)

#define LDFS_PWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	_result = READ_WORD(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_FPR_W(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFS_PWL,		0x00,
	"ldf%cs",		"%D,[%n,-#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFD_PWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	_result = READ_QWORD(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_FPR_Q(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFD_PWL,		0x01,
	"ldf%cd",		"%D,[%n,-#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(STFE_PSTFP_P_LINK)

#define STFE_P_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	/* FIXME: need to load an extended word here... */		\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(RN) - FPOFS, _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STFE_P,			0x00,
	"stf%ce",		"%D,[%n,-#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFP_P_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(STFP_P,			0x01,
	"stf%cp",		"%D,[%n,-#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LDFE_PLLDFP_PL_LINK)

#define LDFE_PL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	/* FIXME: need to load an extended word here... */		\
	_result = READ_QWORD(GPR_EX(RN) - FPOFS, _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_FPR_Q(FD, _result);						\
      }									\
  }
DEFINST(LDFE_PL,		0x00,
	"ldf%ce",		"%D,[%n,-#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFP_PL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(LDFP_PL,		0x01,
	"ldf%cp",		"%D,[%n,-#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(STFE_PWSTFP_PW_LINK)

#define STFE_PW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
	md_addr_t _addr;						\
									\
	/* FIXME: need to load an extended word here... */		\
	_addr = GPR_EX(RN) - FPOFS;					\
	WRITE_QWORD(FPR_Q(FD), _addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFE_PW,		0x00,
	"stf%ce",		"%D,[%n,-#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFP_PW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(STFP_PW,		0x01,
	"stf%cp",		"%D,[%n,-#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LDFE_PWLLDFP_PWL_LINK)

#define LDFE_PWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	/* FIXME: need to load an extended word here... */		\
	_addr = GPR_EX(RN) - FPOFS;					\
	_result = READ_QWORD(_addr, _fault);				\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
									\
	SET_FPR_Q(FD, _result);						\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFE_PWL,		0x00,
	"ldf%ce",		"%D,[%n,-#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFP_PWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(LDFP_PWL,		0x01,
	"ldf%cp",		"%D,[%n,-#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(STFS_PUSTFD_PU_LINK)

#define STFS_PU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        WRITE_WORD(FPR_W(FD), GPR_EX(RN) + FPOFS, _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STFS_PU,		0x00,
	"stf%cs",		"%D,[%n,#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFD_PU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        WRITE_QWORD(FPR_Q(FD), GPR_EX(RN) + FPOFS, _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STFD_PU,		0x01,
	"stf%cd",		"%D,[%n,#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(RN), DNA)


CONNECT(LDFS_PULLDFD_PUL_LINK)

#define LDFS_PUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _result;							\
        enum md_fault_type _fault;					\
									\
        _result = READ_WORD(GPR_EX(RN) + FPOFS, _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_FPR_W(FD, _result);						\
      }									\
  }
DEFINST(LDFS_PUL,		0x00,
	"ldf%cs",		"%D,[%n,#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFD_PUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        qword_t _result;						\
        enum md_fault_type _fault;					\
									\
        _result = READ_QWORD(GPR_EX(RN) + FPOFS, _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_FPR_Q(FD, _result);						\
      }									\
  }
DEFINST(LDFD_PUL,		0x01,
	"ldf%cd",		"%D,[%n,#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(STFS_PUWSTFD_PUW_LINK)

#define STFS_PUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        md_addr_t _addr;						\
									\
        _addr = GPR_EX(RN) + FPOFS;					\
        WRITE_WORD(FPR_W(FD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFS_PUW,		0x00,
	"stf%cs",		"%D,[%n,#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFD_PUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        md_addr_t _addr;						\
									\
        _addr = GPR_EX(RN) + FPOFS;					\
        WRITE_QWORD(FPR_Q(FD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFD_PUW,		0x01,
	"stf%cd",		"%D,[%n,#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)


CONNECT(LDFS_PUWLLDFD_PUWL_LINK)

#define LDFS_PUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _result;							\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) + FPOFS;					\
        _result = READ_WORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_FPR_W(FD, _result);						\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFS_PUWL,		0x00,
	"ldf%cs",		"%D,[%n,#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFD_PUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        qword_t _result;						\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
        _addr = GPR_EX(RN) + FPOFS;					\
        _result = READ_QWORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_FPR_Q(FD, _result);						\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFD_PUWL,		0x01,
	"ldf%cd",		"%D,[%n,#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)


CONNECT(STFE_PUSTFP_PU_LINK)

#define STFE_PU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
									\
        WRITE_QWORD(FPR_Q(FD), GPR_EX(RN) + FPOFS, _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
      }									\
  }
DEFINST(STFE_PU,		0x00,
	"stf%ce",		"%D,[%n,#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFP_PU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(STFP_PU,		0x01,
	"stf%cp",		"%D,[%n,#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LDFE_PULLDFP_PUL_LINK)

#define LDFE_PUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        word_t _result;							\
        enum md_fault_type _fault;					\
									\
        _result = READ_WORD(GPR_EX(RN) + FPOFS, _fault);		\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_FPR_W(FD, _result);						\
      }									\
  }
DEFINST(LDFE_PUL,		0x00,
	"ldf%ce",		"%D,[%n,#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFP_PUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(LDFP_PUL,		0x01,
	"ldf%cp",		"%D,[%n,#%O]",
	RdPort,			F_MEM|F_LOAD|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(STFE_PUWSTFP_PUW_LINK)

#define STFE_PUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        enum md_fault_type _fault;					\
        md_addr_t _addr;						\
									\
	/* FIXME: need to load an extended word here... */		\
        _addr = GPR_EX(RN) + FPOFS;					\
        WRITE_QWORD(FPR_Q(FD), _addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(STFE_PUW,		0x00,
	"stf%ce",		"%D,[%n,#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DGPR(RN), DNA, DNA,	DFPR(FD), /**/DCOND, DGPR(RN), DNA)

#define STFP_PUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(STFP_PUW,		0x01,
	"stf%cp",		"%D,[%n,#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LDFE_PUWLLDFP_PUWL_LINK)

#define LDFE_PUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        qword_t _result;						\
        md_addr_t _addr;						\
        enum md_fault_type _fault;					\
									\
	/* FIXME: need to load an extended word here... */		\
        _addr = GPR_EX(RN) + FPOFS;					\
        _result = READ_QWORD(_addr, _fault);				\
        if (_fault != md_fault_none)					\
          DECLARE_FAULT(_fault);					\
									\
        SET_FPR_Q(FD, _result);						\
        SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LDFE_PUWL,		0x00,
	"ldf%ce",		"%D,[%n,#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP|F_CISC,
	DFPR(FD),DGPR(RN),DNA,	DNA, /**/DCOND, DGPR(RN), DNA)

#define LDFP_PUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	/* FIXME: todo... */						\
	DECLARE_FAULT(md_fault_unimpl);					\
      }									\
  }
DEFINST(LDFP_PUWL,		0x01,
	"ldf%cp",		"%D,[%n,#%O]!",
	RdPort,			F_MEM|F_LOAD|F_DISP/*|F_CISC*/,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

CONNECT(LFMSFMPOST_LINK)

/* SFM, 0x00 */

/* LFM, 0x01 */

#define SFM_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    WRITE_QWORD(FPR_Q((FD)+_i), GPR_EX(RN)+_i*8, _fault);	\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(SFM_W,			0x02,
	"sfm%c",		"%D,%C,[%n],-#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define LFM_WL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    _result = READ_QWORD(GPR_EX(RN)+_i*8, _fault);		\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	    SET_FPR_Q((FD)+_i, _result);				\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LFM_WL,			0x03,
	"lfm%c",		"%D,%C,[%n],-#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define SFM_UW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    WRITE_QWORD(FPR_Q((FD)+_i), GPR_EX(RN)+_i*8, _fault);	\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(SFM_UW,			0x0a,
	"sfm%c",		"%D,%C,[%n],#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define LFM_UWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    _result = READ_QWORD(GPR_EX(RN)+_i*8, _fault);		\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	    SET_FPR_Q((FD)+_i, _result);				\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LFM_UWL,		0x0b,
	"lfm%c",		"%D,%C,[%n],#%O",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


CONNECT(LFMSFMPRE_LINK)

#define SFM_P_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    WRITE_QWORD(FPR_Q((FD)+_i), _addr+_i*8, _fault);		\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	  }								\
      }									\
  }
DEFINST(SFM_P,			0x00,
	"sfm%c",		"%D,%C,[%n,-#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define LFM_PL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    _result = READ_QWORD(_addr+_i*8, _fault);			\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	    SET_FPR_Q((FD)+_i, _result);				\
	  }								\
      }									\
  }
DEFINST(LFM_PL,			0x01,
	"lfm%c",		"%D,%C,[%n,-#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define SFM_PW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    WRITE_QWORD(FPR_Q((FD)+_i), _addr+_i*8, _fault);		\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(SFM_PW,			0x02,
	"sfm%c",		"%D,%C,[%n,-#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define LFM_PWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) - FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    _result = READ_QWORD(_addr+_i*8, _fault);			\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	    SET_FPR_Q((FD)+_i, _result);				\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LFM_PWL,		0x03,
	"lfm%c",		"%D,%C,[%n,-#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define SFM_PU_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    WRITE_QWORD(FPR_Q((FD)+_i), _addr+_i*8, _fault);		\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	  }								\
      }									\
  }
DEFINST(SFM_PU,			0x08,
	"sfm%c",		"%D,%C,[%n,#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define LFM_PUL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    _result = READ_QWORD(_addr+_i*8, _fault);			\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	    SET_FPR_Q((FD)+_i, _result);				\
	  }								\
      }									\
  }
DEFINST(LFM_PUL,		0x09,
	"lfm%c",		"%D,%C,[%n,#%O]",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define SFM_PUW_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    WRITE_QWORD(FPR_Q((FD)+_i), _addr+_i*8, _fault);		\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(SFM_PUW,		0x0a,
	"sfm%c",		"%D,%C,[%n,#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)

#define LFM_PUWL_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	int _i, _count = FCNT ? FCNT : 4;				\
	md_addr_t _addr;						\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_addr = GPR_EX(RN) + FPOFS;					\
	for (_i=0; _i < _count; _i++)					\
	  {								\
	    _result = READ_QWORD(_addr+_i*8, _fault);			\
	    if (_fault != md_fault_none)				\
	      DECLARE_FAULT(_fault);					\
	    SET_FPR_Q((FD)+_i, _result);				\
	  }								\
									\
	SET_GPR(RN, _addr);						\
      }									\
  }
DEFINST(LFM_PUWL,		0x0b,
	"lfm%c",		"%D,%C,[%n,#%O]!",
	WrPort,			F_MEM|F_STORE|F_DISP|F_CISC,
	DNA, DNA, DNA,		DCOND, DNA, DNA, DNA)


/*
 * UOP definitions
 */

/* address generation UOPs */
#define AGEN_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(URD, GPR_EX(URN) - SHIFTRM(GPR(RM), /* unused */0, PSR_C));\
      }									\
  }
DEFUOP(AGEN,
       "agen%c",		"%v,%u,-%m",
       IntALU,			F_ICOMP|F_AGEN,
       DGPR(URD), DNA, DNA,	DCONDSH, DGPR(URN), DGPR(RM), DNA)

#define AGEN_U_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(URD, GPR_EX(URN) + SHIFTRM(GPR(RM), /* unused */0, PSR_C));\
      }									\
  }
DEFUOP(AGEN_U,
       "agen%c",		"%v,%u,%m",
       IntALU,			F_ICOMP|F_AGEN,
       DGPR(URD), DNA, DNA,	DCONDSH, DGPR(URN), DGPR(RM), DNA)

#define AGENI_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(URD, GPR_EX(URN) - OFS);				\
      }									\
  }
DEFUOP(AGENI,
       "agen%c",		"%v,%u,-%o",
       IntALU,			F_ICOMP|F_AGEN,
       DGPR(URD), DNA, DNA,	DCOND, DGPR(URN), DNA, DNA)

#define AGENI_U_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
        SET_GPR(URD, GPR_EX(URN) + OFS);				\
      }									\
  }
DEFUOP(AGENI_U,
       "agen%c",		"%v,%u,%o",
       IntALU,			F_ICOMP|F_AGEN,
       DGPR(URD), DNA, DNA,	DCOND, DGPR(URN), DNA, DNA)

/* load/store primitives */
#define STP_B_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_BYTE((byte_t)GPR_MEM(RD), GPR_EX(URN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFUOP(STP_B,
       "stp%cb",		"%d,[%u]",
       WrPort,			F_MEM|F_STORE|F_DISP,
       DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(URN), DNA)

#define LDP_B_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFUOP(LDP_B,
       "ldp%cb",		"%d,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)

#define LDP_SB_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	byte_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_BYTE(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_GPR(RD, (word_t)(sword_t)(sbyte_t)_result);			\
      }									\
  }
DEFUOP(LDP_SB,
       "ldp%csb",		"%d,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)

#define STP_H_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_HALF((half_t)GPR_MEM(RD), GPR_EX(URN), _fault);		\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFUOP(STP_H,
       "stp%ch",		"%d,[%u]",
       WrPort,			F_MEM|F_STORE|F_DISP,
       DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(URN), DNA)

#define LDP_H_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_GPR(RD, (word_t)_result);					\
      }									\
  }
DEFUOP(LDP_H,
       "ldp%ch",		"%d,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)

#define LDP_SH_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	half_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_HALF(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_GPR(RD, (word_t)(sword_t)(shalf_t)_result);			\
      }									\
  }
DEFUOP(LDP_SH,
       "ldp%csh",		"%d,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)

#define STP_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(GPR_MEM(RD), GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFUOP(STP_W,
       "stp%c",			"%d,[%u]",
       WrPort,			F_MEM|F_STORE|F_DISP,
       DNA, DNA, DNA,		DGPR(RD), /**/DCOND, DGPR(URN), DNA)

#define LDP_W_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_GPR(RD, _result);						\
      }									\
  }
DEFUOP(LDP_W,
       "ldp%c",			"%d,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DGPR(RD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)

#define STP_S_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_WORD(FPR_W(FD), GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFUOP(STP_S,
       "stp%cs",		"%D,[%u]",
       WrPort,			F_MEM|F_STORE|F_DISP,
       DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(URN), DNA)

#define LDP_S_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	word_t _result;							\
	enum md_fault_type _fault;					\
									\
	_result = READ_WORD(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_FPR_W(FD, _result);						\
      }									\
  }
DEFUOP(LDP_S,
       "ldp%cs",		"%D,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)

#define STP_D_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFUOP(STP_D,
       "stp%cd",		"%D,[%u]",
       WrPort,			F_MEM|F_STORE|F_DISP,
       DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(URN), DNA)

#define LDP_D_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_QWORD(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_FPR_Q(FD, _result);						\
      }									\
  }
DEFUOP(LDP_D,
       "ldp%cd",		"%D,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)

#define STP_E_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	enum md_fault_type _fault;					\
									\
	WRITE_QWORD(FPR_Q(FD), GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
      }									\
  }
DEFUOP(STP_E,
       "stp%ce",		"%D,[%u]",
       WrPort,			F_MEM|F_STORE|F_DISP,
       DNA, DNA, DNA,		DFPR(FD), /**/DCOND, DGPR(URN), DNA)

#define LDP_E_IMPL							\
  {									\
    if (COND_VALID(PSR))						\
      {									\
	qword_t _result;						\
	enum md_fault_type _fault;					\
									\
	_result = READ_QWORD(GPR_EX(URN), _fault);			\
	if (_fault != md_fault_none)					\
	  DECLARE_FAULT(_fault);					\
	SET_FPR_Q(FD, _result);						\
      }									\
  }
DEFUOP(LDP_E,
       "ldp%ce",		"%D,[%u]",
       WrPort,			F_MEM|F_LOAD|F_DISP,
       DFPR(FD), DNA, DNA,	DNA, /**/DCOND, DGPR(URN), DNA)


/* clean up all definitions... */
#undef BR_IMPL
#undef BRL_IMPL
#undef SWI_IMPL
#undef AND_IMPL
#undef ANDS_IMPL
#undef EOR_IMPL
#undef EORS_IMPL
#undef SUB_IMPL
#undef SUBS_IMPL
#undef RSB_IMPL
#undef RSBS_IMPL
#undef ADD_IMPL
#undef ADDS_IMPL
#undef ADC_IMPL
#undef ADCS_IMPL
#undef SBC_IMPL
#undef SBCS_IMPL
#undef RSC_IMPL
#undef RSCS_IMPL
#undef TSTS_IMPL
#undef TEQS_IMPL
#undef CMPS_IMPL
#undef CMNS_IMPL
#undef ORR_IMPL
#undef ORRS_IMPL
#undef MOV_IMPL
#undef MOVS_IMPL
#undef BIC_IMPL
#undef BICS_IMPL
#undef MVN_IMPL
#undef MVNS_IMPL
#undef MRS_CPSR_IMPL
#undef TST_IMPL
#undef SWP_IMPL
#undef TEQ_IMPL
#undef MSR_CPSR_IMPL
#undef MRS_SPSR_IMPL
#undef CMP_IMPL
#undef SWP1_IMPL
#undef TST1_IMPL
#undef MSR_SPSR_IMPL
#undef ANDI_IMPL
#undef ANDSI_IMPL
#undef EORI_IMPL
#undef EORSI_IMPL
#undef SUBI_IMPL
#undef SUBSI_IMPL
#undef RSBI_IMPL
#undef RSBSI_IMPL
#undef ADDI_IMPL
#undef ADDSI_IMPL
#undef ADCI_IMPL
#undef ADCSI_IMPL
#undef SBCI_IMPL
#undef SBCSI_IMPL
#undef RSCI_IMPL
#undef RSCSI_IMPL
#undef TSTI_IMPL
#undef TSTSI_IMPL
#undef TEQSI_IMPL
#undef CMPI_IMPL
#undef CMPSI_IMPL
#undef CMNSI_IMPL
#undef ORRI_IMPL
#undef ORRSI_IMPL
#undef MOVI_IMPL
#undef MOVSI_IMPL
#undef BICI_IMPL
#undef BICSI_IMPL
#undef MVNI_IMPL
#undef MVNSI_IMPL
#undef TEQI_IMPL
#undef MRSI_CPSR_IMPL
#undef TSTI1_IMPL
#undef MRSI_SPSR_IMPL
#undef MUL_IMPL
#undef MULS_IMPL
#undef MLA_IMPL
#undef MLAS_IMPL
#undef UMULL_IMPL
#undef UMULLS_IMPL
#undef UMLAL_IMPL
#undef UMLALS_IMPL
#undef SMULL_IMPL
#undef SMULLS_IMPL
#undef SMLAL_IMPL
#undef SMLALS_IMPL
#undef STRH_R_IMPL
#undef LDRH_RL_IMPL
#undef STRH_O_IMPL
#undef LDRH_OL_IMPL
#undef STRH_RU_IMPL
#undef LDRH_RUL_IMPL
#undef STRH_OU_IMPL
#undef LDRH_OUL_IMPL
#undef LDRSB_RL_IMPL
#undef LDRSB_OL_IMPL
#undef LDRSB_RUL_IMPL
#undef LDRSB_OUL_IMPL
#undef LDRSH_RL_IMPL
#undef LDRSH_OL_IMPL
#undef LDRSH_RUL_IMPL
#undef LDRSH_OUL_IMPL
#undef STRH_PR_IMPL
#undef LDRH_PRL_IMPL
#undef STRH_PRW_IMPL
#undef LDRH_PRWL_IMPL
#undef STRH_PO_IMPL
#undef LDRH_POL_IMPL
#undef STRH_POW_IMPL
#undef LDRH_POWL_IMPL
#undef STRH_PRU_IMPL
#undef LDRH_PRUL_IMPL
#undef STRH_PRUW_IMPL
#undef LDRH_PRUWL_IMPL
#undef STRH_POU_IMPL
#undef LDRH_POUL_IMPL
#undef STRH_POUW_IMPL
#undef LDRH_POUWL_IMPL
#undef LDRSB_PRL_IMPL
#undef LDRSB_PRWL_IMPL
#undef LDRSB_POL_IMPL
#undef LDRSB_POWL_IMPL
#undef LDRSB_PRUL_IMPL
#undef LDRSB_PRUWL_IMPL
#undef LDRSB_POUL_IMPL
#undef LDRSB_POUWL_IMPL
#undef LDRSH_PRL_IMPL
#undef LDRSH_PRWL_IMPL
#undef LDRSH_POL_IMPL
#undef LDRSH_POWL_IMPL
#undef LDRSH_PRUL_IMPL
#undef LDRSH_PRUWL_IMPL
#undef LDRSH_POUL_IMPL
#undef LDRSH_POUWL_IMPL
#undef STR_IMPL
#undef LDR_L_IMPL
#undef STR_B_IMPL
#undef LDR_BL_IMPL
#undef STR_U_IMPL
#undef LDR_UL_IMPL
#undef STR_UB_IMPL
#undef LDR_UBL_IMPL
#undef STR_P_IMPL
#undef LDR_PL_IMPL
#undef STR_PW_IMPL
#undef LDR_PWL_IMPL
#undef STR_PB_IMPL
#undef LDR_PBL_IMPL
#undef STR_PBW_IMPL
#undef LDR_PBWL_IMPL
#undef STR_PU_IMPL
#undef LDR_PUL_IMPL
#undef STR_PUW_IMPL
#undef LDR_PUWL_IMPL
#undef STR_PUB_IMPL
#undef LDR_PUBL_IMPL
#undef STR_PUBW_IMPL
#undef LDR_PUBWL_IMPL
#undef STR_R_IMPL
#undef LDR_RL_IMPL
#undef STR_RB_IMPL
#undef LDR_RBL_IMPL
#undef STR_RU_IMPL
#undef LDR_RUL_IMPL
#undef STR_RUB_IMPL
#undef LDR_RUBL_IMPL
#undef STR_RP_IMPL
#undef LDR_RPL_IMPL
#undef STR_RPW_IMPL
#undef LDR_RPWL_IMPL
#undef STR_RPB_IMPL
#undef LDR_RPBL_IMPL
#undef STR_RPBW_IMPL
#undef LDR_RPBWL_IMPL
#undef STR_RPU_IMPL
#undef LDR_RPUL_IMPL
#undef STR_RPUW_IMPL
#undef LDR_RPUWL_IMPL
#undef STR_RPUB_IMPL
#undef LDR_RPUBL_IMPL
#undef STR_RPUBW_IMPL
#undef LDR_RPUBWL_IMPL
#undef STM_IMPL
#undef LDM_L_IMPL
#undef STM_W_IMPL
#undef LDM_WL_IMPL
#undef STM_U_IMPL
#undef LDM_UL_IMPL
#undef STM_UW_IMPL
#undef LDM_UWL_IMPL
#undef STM_P_IMPL
#undef LDM_PL_IMPL
#undef STM_PW_IMPL
#undef LDM_PWL_IMPL
#undef STM_PU_IMPL
#undef LDM_PUL_IMPL
#undef STM_PUW_IMPL
#undef LDM_PUWL_IMPL
#undef ADF_IMPL
#undef ADFI_IMPL
#undef MVF_IMPL
#undef MVFI_IMPL
#undef MUF_IMPL
#undef MUFI_IMPL
#undef MNF_IMPL
#undef MNFI_IMPL
#undef SUF_IMPL
#undef SUFI_IMPL
#undef ABS_IMPL
#undef ABSI_IMPL
#undef RSF_IMPL
#undef RSFI_IMPL
#undef RND_IMPL
#undef RNDI_IMPL
#undef DVF_IMPL
#undef DVFI_IMPL
#undef SQT_IMPL
#undef SQTI_IMPL
#undef RDF_IMPL
#undef RDFI_IMPL
#undef LOG_IMPL
#undef LOGI_IMPL
#undef POW_IMPL
#undef POWI_IMPL
#undef LGN_IMPL
#undef LGNI_IMPL
#undef RPW_IMPL
#undef RPWI_IMPL
#undef EXP_IMPL
#undef EXPI_IMPL
#undef RMF_IMPL
#undef RMFI_IMPL
#undef SIN_IMPL
#undef SINI_IMPL
#undef FML_IMPL
#undef FMLI_IMPL
#undef COS_IMPL
#undef COSI_IMPL
#undef FDV_IMPL
#undef FDVI_IMPL
#undef TAN_IMPL
#undef TANI_IMPL
#undef FRD_IMPL
#undef FRDI_IMPL
#undef ASN_IMPL
#undef ASNI_IMPL
#undef POL_IMPL
#undef POLI_IMPL
#undef ACS_IMPL
#undef ACSI_IMPL
#undef ATN_IMPL
#undef ATNI_IMPL
#undef FURD_IMPL
#undef FURDI_IMPL
#undef NRM_IMPL
#undef NRMI_IMPL
#undef CDP_IMPL
#undef FLT_IMPL
#undef FIX_IMPL
#undef WFS_IMPL
#undef RFS_IMPL
#undef WFC_IMPL
#undef RFC_IMPL
#undef CMF_IMPL
#undef CMFI_IMPL
#undef CNF_IMPL
#undef CNFI_IMPL
#undef CMFE_IMPL
#undef CMFEI_IMPL
#undef CNFE_IMPL
#undef CNFEI_IMPL
#undef STFS_W_IMPL
#undef STFD_W_IMPL
#undef LDFS_WL_IMPL
#undef LDFD_WL_IMPL
#undef STFE_W_IMPL
#undef STFP_W_IMPL
#undef LDFE_WL_IMPL
#undef LDFP_WL_IMPL
#undef STFS_UW_IMPL
#undef STFD_UW_IMPL
#undef LDFS_UWL_IMPL
#undef LDFD_UWL_IMPL
#undef STFE_UW_IMPL
#undef STFP_UW_IMPL
#undef LDFE_UWL_IMPL
#undef LDFP_UWL_IMPL
#undef STFS_P_IMPL
#undef STFD_P_IMPL
#undef LDFS_PL_IMPL
#undef LDFD_PL_IMPL
#undef STFS_PW_IMPL
#undef STFD_PW_IMPL
#undef LDFS_PWL_IMPL
#undef LDFD_PWL_IMPL
#undef STFE_P_IMPL
#undef STFP_P_IMPL
#undef LDFE_PL_IMPL
#undef LDFP_PL_IMPL
#undef STFE_PW_IMPL
#undef STFP_PW_IMPL
#undef LDFE_PWL_IMPL
#undef LDFP_PWL_IMPL
#undef STFS_PU_IMPL
#undef STFD_PU_IMPL
#undef LDFS_PUL_IMPL
#undef LDFD_PUL_IMPL
#undef STFS_PUW_IMPL
#undef STFD_PUW_IMPL
#undef LDFS_PUWL_IMPL
#undef LDFD_PUWL_IMPL
#undef STFE_PU_IMPL
#undef STFP_PU_IMPL
#undef LDFE_PUL_IMPL
#undef LDFP_PUL_IMPL
#undef STFE_PUW_IMPL
#undef STFP_PUW_IMPL
#undef LDFE_PUWL_IMPL
#undef LDFP_PUWL_IMPL
#undef SFM_W_IMPL
#undef LFM_WL_IMPL
#undef SFM_UW_IMPL
#undef LFM_UWL_IMPL
#undef SFM_P_IMPL
#undef LFM_PL_IMPL
#undef SFM_PW_IMPL
#undef LFM_PWL_IMPL
#undef SFM_PU_IMPL
#undef LFM_PUL_IMPL
#undef SFM_PUW_IMPL
#undef LFM_PUWL_IMPL
#undef AGEN_IMPL
#undef AGEN_U_IMPL
#undef AGENI_IMPL
#undef AGENI_U_IMPL
#undef STP_B_IMPL
#undef LDP_B_IMPL
#undef LDP_SB_IMPL
#undef STP_H_IMPL
#undef LDP_H_IMPL
#undef LDP_SH_IMPL
#undef STP_W_IMPL
#undef LDP_W_IMPL
#undef STP_S_IMPL
#undef LDP_S_IMPL
#undef STP_D_IMPL
#undef LDP_D_IMPL
#undef STP_E_IMPL
#undef LDP_E_IMPL

#undef DEFINST
#undef DEFUOP
#undef DEFLINK
#undef CONNECT
